Downsample data to save space
pupiltimecourse.data is dowsnampled but doesn’t have all participants < 400
but the script pupiltimecourseexp2.Rmd has what we need to do the same dowsnampling
Goal - take pupil timecourse, dowsnample and then mrge it it behavioural data so that we can do the additional arousal pupil analyses that check for timecourse things.
check gazeR or downsampling
to do, do the same arousal correlation with valence
nrow(tmp.df4_full_stim_downs_jun2021_with_beh2)
[1] 87529
pupil arousal
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, mediansplit_self_arousal, Alexithymia, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_self_arousal, pup_basCor, color = mediansplit_self_arousal,fill = mediansplit_self_arousal))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
# xlab("Arousal")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_self_valence)
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

brightness

Participants section
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(Group == "NT")%>%
# subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, mediansplit_ground_arousal, Alexithymia, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_arousal, pup_basCor, color = mediansplit_ground_arousal,fill = mediansplit_ground_arousal))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
# xlab("Arousal")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_ground_valence)
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, mediansplit_ground_arousal, Alexithymia, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_arousal, Mean, color = mediansplit_ground_arousal,fill = mediansplit_ground_arousal))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
# xlab("Arousal")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_ground_valence)+
# facet_grid(~BRIGHTNESS_mediansplit)+
ylim(90,130)
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

okay let’s create averages frio this entire sample and use those to devide the stimuli
self aropusal might be biased by problematic folks but averages for the entire sample should not
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid_num< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, self_arousal_lab, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(self_arousal_lab, pup_basCor, color = self_arousal_lab,fill = self_arousal_lab))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
# xlab("Arousal")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_self_valence)
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid_num< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, ground_arousal_lab, Alexithymia, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(ground_arousal_lab, pup_basCor, color = ground_arousal_lab,fill = ground_arousal_lab))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
xlab("Arousal")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

Resposne bias

ceiliing effect?
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, stimIAPS, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, pup_basCor))+
geom_point()+
# stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Arousal")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()+
ylim(-3.3,1.3)
ceiling effect?
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(mediansplit_ground_valence)%>%
mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
group_by(mediansplit_ground_valence)%>%
mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, pup_basCor))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary( geom = 'pointrange', alpha = .4, size = 1, colour = "Black") +
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
Ignoring unknown parameters: fun.y

db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(mediansplit_ground_valence)%>%
mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
group_by(mediansplit_ground_valence)%>%
mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, pup_basCor))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary( geom = 'pointrange', alpha = .4, size = 1, colour = "Black") +
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_self_valence, pup_basCor))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary( geom = 'pointrange', alpha = .5, size = 1, colour = "Black") +
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
# db_full4new_stim_screen_pupil_nopract$arousal_outler
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, mediansplit_sample_arousal2, mediansplit_sample_valence2)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_sample_arousal2, arousal))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary( geom = 'pointrange', alpha = .5, size = 1, colour = "Black") +
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_sample_valence2)+
ggpubr::stat_cor()
Ignoring unknown parameters: fun.y

otehr confounds - eye movements
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, mean_fix_dur))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
unique(db_full4new_stim_screen_pupil_nopract$ValenceMeanThisSample)
median(db_full4new_stim_screen_pupil_nopract$ValenceMeanThisSample)
median(db_full4new_stim_screen_pupil_nopract$valence)
median(db_full4new_stim_screen_pupil_nopract$arousal)
median(db_full4new_stim_screen_pupil_nopract$ArousalMeanThisSample)
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_self_valence, mean_fix_dur))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
# data loss gaze
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, fix_count))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, SacAmp))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, sdevgaze))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, gaze_loss_prop))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
ylim(-3.3,1.3)
db_full4new_stim_screen_pupil_nopract%>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_mean = mean(pup_basCor, na.rm = TRUE), sd_pup = sd(pup_basCor, na.rm = TRUE), subj = n())%>%
group_by(ssid, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(mediansplit_ground_valence)%>%
# mutate(pup_basCor_se = sd_pup/(sqrt(subj)))%>%
ggplot(aes(mediansplit_ground_valence, total_fix_dur))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(geom = 'pointrange', alpha = .1, size = 1, colour = "Black") +
# geom_errorbar(aes(ymin = pup_basCor_mean-pup_basCor_se, ymax = pup_basCor_mean+pup_basCor_se ))+
geom_smooth(method = 'lm', se = F)+
p$graphstyle+
xlab("Valence")+
# ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
let’s model it formally
remember baseline corection is equivalendt to stimuli intercept
pupil_arousal_findings<- list()
library(lmerTest)
unique(db_full4new_stim_screen_pupil_nopract$stimIAPS)
unique(substr(db_full4new_stim_screen_pupil_nopract$stimIAPS, 1,8))
db_full4new_stim_screen_pupil_nopract$Label<- substr(db_full4new_stim_screen_pupil_nopract$stimIAPS, 1,8)
db_full4new_stim_screen_pupil_nopract<- left_join(db_full4new_stim_screen_pupil_nopract, imageJ_IAPS, by = "Label")
nrow(db_full4new_stim_screen_pupil_nopract)
# rows = 2858
db_full4new_stim_screen_pupil_nopract$Mean_gray_z<- scale(db_full4new_stim_screen_pupil_nopract$Mean, center = TRUE, scale = TRUE)[,1]
options(contrasts = c("contr.sum","contr.poly"))
options(scipen = 999)
db_full4new_stim_screen_pupil_nopract$ssid_num <- as.numeric(as.character(db_full4new_stim_screen_pupil_nopract$ssid))
pupil_arousal_findings$pupil_from_arousal <- lmer(pup_basCor ~ arousal_c*Mean_gray_z +(1 +Mean_gray_z | ssid) + (0+arousal_c| ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500 &
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_arousal)
# singularity (drop arousal c slope)
# is there a coorelationbtween mean arousal rating and meagray(
db_full4new_stim_screen_pupil_nopract%>%
group_by(stimIAPS,ground_valence_lab) %>%
summarise_at(c('arousal_c', 'Mean_gray_z'), mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, Mean_gray_z, color = ground_valence_lab))+
geom_point()+
ggpubr::stat_cor()
# <- predict(pupil_arousal_findings$pupil_from_arousal)
db_full4new_stim_screen_pupil_nopract %>%
group_by(stimIAPS) %>%
# summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# summarise_at(c('arousal_c', 'Mean_gray_z'), mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, pup))+
geom_smooth(aes(group = ssid, alpha = ssid), method = 'lm', se = F)
# geom_smooth(aes(group = stimIAPS), method = 'lm', se = F)
ggpubr::stat_cor()
cor.test(db_full4new_stim_screen_pupil_nopract\(, db_full4new_stim_screen_pupil_nopract\))
# if we put brighteness and arousal we see no interaction which means we probably don't need to worry about brighteness, it doesn't change effects of arousal self report
# db_full4new_stim_pupil$pup
pupil_arousal_findings$pupil_from_arousal <- lmer(pup_basCor ~ arousal_c+Mean_gray_z +(1 +Mean_gray_z | ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract$pup, pupil_outlier == FALSE & ssid_num< 500&
arousal_outler == FALSE))
install.packages('usdm')
usdm::vif(as.data.frame(db_full4new_stim_screen_pupil_nopract[,c('arousal', 'valence')]))
pupil_arousal_findings$pupil_from_arousal_withval <- lmer(pup_basCor ~ arousal_c*valence_c* Mean_gray_z +(1 +Mean_gray_z | ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500&
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_arousal_withval)
car::vif(pupil_arousal_findings$pupil_from_arousal_withval)
lmerTest::step(pupil_arousal_findings$pupil_from_arousal_withval)
# control for baseline arousal ratings
pupil_arousal_findings$pupil_from_arousal_withval
summary(lmer(pup_basCor ~ arousal_c*valence_c+ Mean_gray_z +(1 | ssid) + (1|stimIAPS),
# (1|ArousalMean)+ (1|ArousalMean), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & Group == "NT" &
arousal_outler == FALSE)))
# arousal_c:valence_c 0 35.52 35.52 1 2150.19 13.5760 0.0002348 ***
pupil_arousal_findings$arousal_from_pupil <- lmer(arousal ~ pup_basCor * Mean_gray_z +(1+pup_basCor | ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid!= 610&
arousal_outler == FALSE))
summary(pupil_arousal_findings$arousal_from_pupil)
# what about valence
pupil_arousal_findings$pupil_from_valence <- lmer(pup_basCor ~ valence_c+Mean_gray_z +(1 +Mean_gray_z | ssid) +
(0 +valence_c | ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid!= 610&
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_arousal)
summary(pupil_arousal_findings$pupil_from_valence)
Valence and arousal
pupil_arousal_findings$pupil_from_ar_vale <- lmer(pup_basCor ~ (valence_c* arousal_c) + Mean_gray_z +
(1 + Mean_gray_z | ssid),
# (0+ valence_c* arousal_c | ssid),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500 &
arousal_outler == FALSE))
db_full4new_stim_screen_pupil_nopract$total_fix_dur_z<- scale(db_full4new_stim_screen_pupil_nopract$total_fix_dur, center = TRUE, scale = TRUE)[,1]
pupil_arousal_findings$pupil_from_ar_val_gaze <- lmer(pup_basCor ~ (valence_c * arousal_c * total_fix_dur_z)+ Mean_gray_z +
+
(1 + Mean_gray_z | ssid),
# (0+ total_fix_dur_z | ssid),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500 &
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_ar_val_gaze )
summary(pupil_arousal_findings$pupil_from_ar_vale)
car::vif(pupil_arousal_findings$pupil_from_ar_val_gaze)
anova(pupil_arousal_findings$pupil_from_ar_vale, pupil_arousal_findings$pupil_from_arousal)
# interaction valence and arousal
control for gaze
# avg fix dur
db_full4new_stim_screen_pupil_nopract$mean_fix_dur_z<- scale(db_full4new_stim_screen_pupil_nopract$mean_fix_dur, center = TRUE, scale = TRUE)[,1]
pupil_arousal_findings$pupil_from_ar_val_gaze <- lmer(pup_basCor ~ (valence_c * arousal_c * mean_fix_dur_z)+ Mean_gray_z +
+
(1 + Mean_gray_z | ssid),
# (0+ total_fix_dur_z | ssid),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500 &
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_ar_val_gaze )
interactions::interact_plot(pupil_arousal_findings$pupil_from_ar_val_gaze , pred = arousal_c, modx = mean_fix_dur_z)
# fix count
db_full4new_stim_screen_pupil_nopract$fix_count_z<- scale(db_full4new_stim_screen_pupil_nopract$fix_count, center = TRUE, scale = TRUE)[,1]
pupil_arousal_findings$pupil_from_ar_val_gaze <- lmer(pup_basCor ~ (valence_c * arousal_c * fix_count_z)+ Mean_gray_z +
+
(1 + Mean_gray_z | ssid),
# (0+ total_fix_dur_z | ssid),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid_num< 500 &
arousal_outler == FALSE))
summary(pupil_arousal_findings$pupil_from_ar_val_gaze )
interactions::interact_plot(pupil_arousal_findings$pupil_from_ar_val_gaze , pred = arousal_c, modx = mean_fix_dur_z)
interactions::interact_plot(pupil_arousal_findings$pupil_from_ar_vale , pred = valence_c, modx = arousal_c)
interactions::interact_plot(pupil_arousal_findings$pupil_from_ar_vale , pred =arousal_c , modx = valence_c)
car::vif(pupil_arousal_findings$pupil_from_ar_vale) #curoff 2.5?
cor.test(db_full4new_stim_screen_pupil_nopract$valence_c, db_full4new_stim_screen_pupil_nopract$arousal_c)
rmcorr_valence_arousal <- rmcorr::rmcorr(participant = "ssid", measure1 = "valence_c", measure2 = "arousal_c", data = db_full4new_stim_screen_pupil_nopract)
plot(rmcorr_valence_arousal)
?rmcorr
db_full4new_stim_screen_pupil_nopract %>%
group_by(stimIAPS)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(ArousalMean, ValenceMean))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
theme_classic()
db_full4new_stim_screen_pupil_nopract %>%
group_by(stimIAPS)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, valence_c))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
theme_classic()
# with arousal as DV
pupil_arousal_findings$aroual_from_pup <- lmer(arousal ~ valence_c*pup_basCor * BRIGHTNESSc + (1| stimIAPS)+
(1 | ssid)+(0 +valence_c | ssid), REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, pupil_outlier == FALSE & ssid!= 610&
arousal_outler == FALSE))
summary(pupil_arousal_findings$aroual_from_pup)
anova(pupil_arousal_findings$aroual_from_pup)
interactions::interact_plot(pupil_arousal_findings$aroual_from_pup , pred = valence_c, modx = pup_basCor)
interactions::interact_plot(pupil_arousal_findings$aroual_from_pup, pred =pup_basCor , modx = valence_c)
# for positive valenced stimuli participants reporte higher arousal to more dilated pupils
#for negatively valence they report feeling negative even when they don't show strog pupil dilation
# same pattern
# pupil is more alighned with objective arousal in the positive trials
mixed model is consistent wth the previous plot, arousal effects on pupil is modulated by valence. in other words there is a consistent effect between pupil and self-repot of arousal more for positive emotions.
analyse the correlationla way since we are aggregating we don’t need to worry too much about brighteness as every person sees every stimuli in all brightness levels CONCORDANCE
db_full4new_stim_screen_pupil_nopract%>%
group_by(mediansplit_self_valence_thissample, stimIAPS)%>%
summarise_at(c("arousal", 'valence'), mean, na.rm = TRUE)%>%
arrange(stimIAPS)
test_anovas<- db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_valence2,mediansplit_sample_arousal2)%>%
mutate(cortest = cor(arousal_c, pup_basCor, use = "complete"))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_valence2,mediansplit_sample_arousal2)%>%
mutate(cortest = cor(arousal_c, pup_basCor, use = "complete"))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_sample_valence2, cortest, color = mediansplit_sample_valence2))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
theme_classic()+
geom_hline(yintercept = .2, linetype = 'dashed', alpha = .2)+
# ggpubr::stat_compare_means(paired = TRUE)+
ggpubr::stat_compare_means()+
facet_grid(~mediansplit_sample_arousal2)
# let's identify the folks that show less of a difference between conditions.
flag_pos_neg<- db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_valence2)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor)$estimate)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
mutate(cor_pos_neg_diff = cortest[mediansplit_sample_valence2 == "More positive"] -
cortest[mediansplit_sample_valence2 == "More negative"])%>%
mutate(cor_pos_neg_diff_lab = if_else(cor_pos_neg_diff>0, "pos > neg", "neg > pos"))%>%
group_by(ssid,cor_pos_neg_diff_lab)%>%
summarise_at(c("cor_pos_neg_diff"), mean, na.rm = TRUE)
# subset(cor_pos_neg_diff<= 0)%>%
ggplot(aes(mediansplit_sample_valence2, cortest, color = mediansplit_sample_valence2))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
theme_classic()+
geom_hline(yintercept = .2, linetype = 'dashed', alpha = .2)
# ggpubr::stat_compare_means(paired = TRUE)+
ggpubr::stat_compare_means()
testcor <-cor(db_full4new_stim_screen_pupil_nopract$arousal, db_full4new_stim_screen_pupil_nopract$valence)
testcor
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_valence2, mediansplit_sample_arousal2)%>%
# mutate(cortest = cor.test(arousal_c, pup_basCor)$estimate)%>%
mutate(cortest = cor(arousal_c, pup_basCor, method = 'kendall'))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_sample_valence2, cortest, color = mediansplit_sample_valence2))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
theme_classic()+
facet_grid(~mediansplit_sample_arousal2)+
geom_hline(yintercept = .2, linetype = 'dashed', alpha = .2)
# ggpubr::stat_compare_means(paired = TRUE)+
# ggpubr::stat_compare_means()
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_arousal2, mediansplit_sample_valence2)%>%
# mutate(cortest = cor.test(arousal_c, pup_basCor)$estimate)%>%
mutate(cortest = cor(valence_c, pup_basCor, method = 'kendall'))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_sample_arousal2, cortest, color = mediansplit_sample_arousal2))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
theme_classic()+
facet_grid(~mediansplit_sample_valence2)+
geom_hline(yintercept = .2, linetype = 'dashed', alpha = .2)
same as plot above but with valence in the correlation
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_sample_arousal2)%>%
mutate(cortest = cor.test(valence_c, pup_basCor)$estimate)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_sample_arousal2, cortest, color = mediansplit_sample_arousal2))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
theme_classic()
# ggpubr::stat_compare_means(paired = TRUE)+
ggpubr::stat_compare_means()
# ground
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_ground_valence)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor, use = "complete")$estimate)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_valence, cortest, color = mediansplit_ground_valence))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .3)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
# ggpubr::stat_compare_means(paired = TRUE)+
# ggpubr::stat_compare_means()
theme_classic()
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_ground_valence, mediansplit_ground_arousal)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor, use = "complete")$estimate)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_valence, cortest, color = mediansplit_ground_valence))+
geom_bar(stat="summary", fun.y = "mean", alpha = .4)+
geom_jitter(width = .1, alpha = .3)+
stat_summary( geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', color = "black", alpha = .1)+
ylab("R pupil vs self report arousal")+
# ggpubr::stat_compare_means(paired = TRUE)+
# ggpubr::stat_compare_means()
theme_classic()+
facet_grid(~mediansplit_ground_arousal)
Ignoring unknown parameters: fun.y

db_pupil_concordance_agg_ground <- db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_ground_valence)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor, use = "complete")$estimate)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)
afex::aov_ez(id = "ssid",
data = db_pupil_concordance_agg,
between = NULL,
within = 'mediansplit_ground_valence',
dv = 'cortest')
unique(db_full4new_stim_screen_pupil_nopract$tNo)
db_pupil_concordance_agg_self <- db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE)%>%
subset( arousal_outler == FALSE & !is.na(Alexithymia))%>%
subset(!is.na(Alexithymia))%>%
# subset(Group == "NT")%>%
subset(ssid_num<500)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_self_arousal, mediansplit_self_valence)%>%
mutate(cortest = cor(arousal_c, pup_basCor, use = "complete"))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)
afex::aov_ez(id = "ssid",
data = test_anovas,
between = NULL,
within = 'mediansplit_sample_valence2',
dv = 'cortest')
afex::aov_ez(id = "ssid",
data = subset(test_anovas, mediansplit_sample_valence2 == "More positive"),
between = NULL,
within = 'mediansplit_sample_arousal2',
dv = 'cortest')
afex::aov_ez(id = "ssid",
data = db_pupil_concordance_agg_self,
between = NULL,
within = 'mediansplit_ground_valence',
dv = 'cortest')
# valence and arousal
afex::aov_ez(id = "ssid",
data = test_anovas,
between = NULL,
within = c('mediansplit_sample_arousal2','mediansplit_sample_valence2'),
dv = 'cortest')
db_parsed_f_summ<- db_parsed_f %>%
group_by(tNo, ssid)%>%
summarise_at(c('Duration', 'mean_x', 'mean_y'), sum, na.rm = TRUE)
ggplot(aes(tNo, Duration))+
stat_summary(geom = 'pointrange')+
geom_point(alpha = .1)
unique(db_parsed_f_summ$ssid)
unique(db_parsed_f_summ$tNo)
unique(db_full4new_stim_screen_pupil_nopract$tNo)
unique(db_full4new_stim_screen_pupil_nopract$ssid)
nrow(db_full4new_stim_screen_pupil_nopract)
nrow(db_parsed_f_summ)
table(is.na(db_parsed_f_summ$ssid))
db_parsed_f_summ$total_fix_dur<- db_parsed_f_summ$Duration
db_parsed_f_summ$tNo<- as.character(db_parsed_f_summ$tNo)
db_parsed_f_summ$ssid<- as.character(db_parsed_f_summ$ssid)
db_full4new_stim_screen_pupil_nopract$Duration<- NULL
db_full4new_stim_screen_pupil_nopract$total_fix_dur<- NULL
db_full4new_stim_screen_pupil_nopract<- left_join(db_full4new_stim_screen_pupil_nopract, db_parsed_f_summ)
I HAVE THE IMPRESSION THAT WHAT THIS ANALYSES GIVES US IS THE SAME AS THE MIXED MODEL AS THIS CONCIORDANCE CAN BE EXPRESSED IN TERMS FO THE SLOPE OF THE AOUSAL AND PUPIL RELATION
SO ION OTHER WORDS IS not that pupil tracksvalence is that arousal based pupil is modulated by valence
by why is that - bias is responding? eg.. people response they feel negative even when they don’t (ie. when we have no objective indicator that they do feel) - is it something about the stimuli, positive arousal is sexual here? - or arousal interferes with appraisal. high arousing stimuli are distracting??
timecourse models of pupil
Pupil tracks valence
db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler== FALSE)%>%
subset(ssid< 500)%>%
subset(pupil_outlier == FALSE)%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, self_arousal_lab, Alexithymia, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(self_arousal_lab, pup_basCor, color = self_arousal_lab,fill = self_arousal_lab))+
geom_hline(yintercept = 0, linetype = "dashed", size = 2, alpha = .2)+
# geom_half_violin(colour = FALSE, alpha = .3, size = 5)+
geom_bar(stat="summary", fun.y = "mean", alpha = .4, color = FALSE)+
geom_jitter(width = .1, alpha=.2)+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1, size = 1, colour = "Black") +
stat_summary(geom = 'pointrange', width =1)+
p$graphstyle+
xlab("Arousal")+
ylab("Baseline corrected pupil")+
scale_color_brewer(palette = "Dark2")+
scale_fill_brewer(palette = "Dark2")+
facet_grid(~mediansplit_self_valence)
Ignoring unknown parameters: fun.yIgnoring unknown parameters: width

combine timecourse
let’s put pupil scr and ht prediction on subjective arousal
rm(justone_test, lucy_plots, test)
# import the timecourse
tmp.df4_full_stim_downs_jun2021 <- readRDS("~/OneDrive - Nexus365/InteroStudy2020/analysis/DataAnalysisJanuary2020/DataAnalysisJan2020/tmp.df4_full_stim_downs_jun2021.rds")
# merge with behavioural data
unique(db_full4new_stim_screen_pupil_nopract$ssid)
colnames(db_full4new_stim_screen_pupil_nopract)
colnames(tmp.df4_full_stim_downs_jun2021)
db_full4new_stim
colnames(db_full4new_stim_screen_pupil_nopract)
db_full4new_stim_subset<- db_full4new_stim_screen_pupil_nopract[,c(1:4,6:7,12:13,16,21:27, 31:56,80:81,84:96,98:114,116:124)]
# match types of merging variables
tmp.df4_full_stim_downs_jun2021_with_beh2$ssid<- as.character(tmp.df4_full_stim_downs_jun2021_with_beh2$ssid)
db_full4new_stim_subset$ssid<- as.character(db_full4new_stim_subset$ssid)
# tNo
tmp.df4_full_stim_downs_jun2021_with_beh2$tNo <- as.character(tmp.df4_full_stim_downs_jun2021_with_beh2$tNo)
db_full4new_stim_subset$tNo <- as.character(db_full4new_stim_subset$tNo)
unique(db_full4new_stim_subset$tNo)
unique(tmp.df4_full_stim_downs_jun2021_with_beh2$tNo)
# merge
nrow(tmp.df4_full_stim_downs_jun2021_with_beh2)
# 172168
# 87529
table(is.na(db_full4new_stim_subset$mediansplit_self_valence))
tmp.df4_full_stim_downs_jun2021_with_beh2$tNo<- as.numeric(tmp.df4_full_stim_downs_jun2021_with_beh2$tNo)
tmp.df4_full_stim_downs_jun2021_with_beh2<- tmp.df4_full_stim_downs_jun2021_with_beh2%>%
arrange(ssid,tNo, timerezero3)
db_full4new_stim_subset$t
tmp.df4_full_stim_downs_jun2021_with_beh<- left_join(tmp.df4_full_stim_downs_jun2021_with_beh2, db_full4new_stim_subset)
unique(db_full4new_stim_subset$stimIAPS)
tmp.df4_full_stim_downs_jun2021_with_beh2$trialUnq
unique(tmp.df4_full_stim_downs_jun2021_with_beh2$ssid)
unique(db_full4new_stim_subset$ssid)
db_full4new_stim_subset$tNo<- as.numeric(db_full4new_stim_subset$tNo)
table(is.na(db_full4new_stim_subset$arousal))
tmp.df4_full_stim_downs_jun2021_with_behnew<- right_join(tmp.df4_full_stim_downs_jun2021_with_beh2, db_full4new_stim_subset,
by = c('ssid', 'tNo'))
nrow(tmp.df4_full_stim_downs_jun2021_with_beh)
# 172168 good
nrow(tmp.df4_full_stim_downs_jun2021_with_beh2)
nrow(tmp.df4_full_stim_downs_jun2021_with_behnew)
87529
table(is.na(tmp.df4_full_stim_downs_jun2021_with_behnew$mediansplit_self_valence))
subset(tmp.df4_full_stim_downs_jun2021_with_behnew, is.na(arousal))
unique(tmp.df4_full_stim_downs_jun2021_with_beh2$trialUnq)
# check
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(ground_arousal_lab))%>%
ggplot(aes(x = timerezero3, y = pup_basCor))+
stat_smooth(aes(group= ground_arousal_lab, color = ground_arousal_lab), fun = mean,geom = "line",
se = F, alpha = .1, size = 1.5)+
stat_smooth(aes(group=ground_arousal_lab, color = ground_arousal_lab), size = 3)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
xlim(0,6)+
facet_grid(~mediansplit_self_valence)
Ignoring unknown parameters: fun

pupil timecourse
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(mediansplit_sample_arousal2))%>%
subset(!is.na(mediansplit_sample_arousal2))%>%
ggplot(aes(x = timerezero3, y = pup_basCor))+
stat_smooth(aes(group= mediansplit_sample_valence2, color = mediansplit_sample_valence2), fun = mean,geom = "line",
se = F, alpha = .1, size = 1.5)+
stat_smooth(aes(group=mediansplit_sample_valence2, color = mediansplit_sample_valence2), size = 3)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
xlim(0,6)+
facet_grid(~mediansplit_sample_arousal2)
Ignoring unknown parameters: fun

unique(tmp.df4_full_stim_downs_jun2021_with_beh$condition)
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(mediansplit_sample_arousal2))%>%
subset(valencearousal_outliers == TRUE) %>%
# subset(!is.na(mediansplit_sample_arousal2))%>%
ggplot(aes(x = timerezero3, y = pup_basCor))+
stat_smooth(aes(group= mediansplit_sample_arousal2, color = mediansplit_sample_arousal2), fun = mean,geom = "line",
se = F, alpha = .1, size = 1.5)+
stat_smooth(aes(group=mediansplit_sample_arousal2, color = mediansplit_sample_arousal2), size = 3)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
xlim(0,6)+
facet_grid(mediansplit_sample_valence2~.)+
geom_hline(yintercept = 0)
Ignoring unknown parameters: fun

unique(tmp.df4_full_stim_downs_jun2021_with_beh$timebin2) # 30 time bins

timecourse analyss using lmer
1- select a bin 2 - fit a lmer 3 - save statistics (estimate and p value) 3 - create clusters (p value < .05 in at least 3 consecutive bins)
tmp.df4_full_stim_downs_jun2021_with_behnew$
i = 1
nbins<- unique(tmp.df4_full_stim_downs_jun2021_with_behnew$timebin2)
tmp.df4_full_stim_downs_jun2021_with_behnew
unique(tmp.df4_full_stim_downs_jun2021_with_behnew$timebin2)
lmer_bin_pup<- list()
# <- nrow(nbins)
nbins<- unique(tmp.df4_full_stim_downs_jun2021_with_behnew$timebin2)
tmp.df4_full_stim_downs_jun2021_with_behnew$Label<- substr(tmp.df4_full_stim_downs_jun2021_with_behnew$stimIAPS, 1,8)
imageJ_IAPS$Label
nrow(tmp.df4_full_stim_downs_jun2021_with_behnew)
# 62921
nrow(left_join(tmp.df4_full_stim_downs_jun2021_with_behnew, imageJ_IAPS))
tmp.df4_full_stim_downs_jun2021_with_behnew<- left_join(tmp.df4_full_stim_downs_jun2021_with_behnew, imageJ_IAPS)
tmp.df4_full_stim_downs_jun2021_with_behnew$Mean_gray_z<- scale(tmp.df4_full_stim_downs_jun2021_with_behnew$Mean, scale = TRUE, center = TRUE)[,1]
test<- lmer(pup_basCor ~ arousal_c+Mean_gray_z +(1 +Mean_gray_z | ssid),
REML = FALSE,
data = subset(tmp.df4_full_stim_downs_jun2021_with_behnew,
timebin2 == nbins[b]))
summary(test)
tmp.df4_full_stim_downs_jun2021_with_behnew$tNo
"(0.0411,0.261]"
subset(tmp.df4_full_stim_downs_jun2021_with_behnew,
timebin2 == nbins[28] & ssid == 341 & tNo == 3)
test
rm(i)
i = 1 # remember to always rezero it
# b = 34
nbins<- nbins[1:28]
unique(nbins)
# nbins<- as
# positive
# create number s for time bins
tmp.df4_full_stim_downs_jun2021_with_behnew<- tmp.df4_full_stim_downs_jun2021_with_behnew%>%
group_by(ssid, stimIAPS)%>%
mutate(timebin_no = 1:n())
tmp.df4_full_stim_downs_jun2021_with_behnew%>%
# group_by(ssid, stimIAPS)
ggplot(aes(timebin_no))+
geom_histogram()+
geom_vline(xintercept = 28)+
geom_hline(yintercept = 200)

negative lmer

timecourse_result_df$Valence <- "More negative"
timecourse_result_df_neg$Valence<- "More positive"
bind_rows(timecourse_result_df,timecourse_result_df_neg)%>%
ggplot(aes(timebins, t, color = Valence))+
geom_line(size = 2)+
geom_line(aes(y = p), linetype = "dashed", size = 2)+
geom_hline(yintercept = .05, color = 'red', size = 1.5)
use valence to pupil

use valence to pupil

valence for high vs low


velocity analyses

Velocity by valence

Negative velocity

A few plots for velocity

tmp.df4_full_stim_downs_jun2021_with_behnew%>%
group_by(mediansplit_self_valence, timebin2)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(timerezero3, cor_arous_pup, color = mediansplit_self_valence))+
# geom_s
stat_summary(fun = mean, geom = 'pointrange')+
stat_summary(aes(y = cor_arous_pup_pval), fun = mean, geom = 'line', linetype = "dashed")+
geom_hline(yintercept = .1, linetype = "dashed")
geom_rect(aes(xmin = timerezero3, xmax = dplyr::lead(timerezero3), ymin =.63 , ymax =.66 , fill = pval_sign),
alpha = 0.8)
# stat_smooth(aes(group = ssid), se = F, alpha = .1)
# mutate(
# model = map(data, ~lm(pup_basCor ~ arousal_c, data = .)),
# cor = map(data, possibly(
# ~tidy(cor.test(.x$pup_basCor, .x$arousal_c), 3), otherwise = data.frame())
# )
# )
self arousal
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(ground_arousal_lab))%>%
ggplot(aes(x = timerezero3, y = pup_basCor))+
stat_smooth(aes(group= ground_arousal_lab, color = ground_arousal_lab), fun = mean,geom = "line",
se = F, alpha = .1, size = 1.5)+
stat_smooth(aes(group=ground_arousal_lab, color = ground_arousal_lab), size = 3)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
xlim(0,6)+
facet_grid(~mediansplit_self_valence)
# plot with valence
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(ground_arousal_lab))%>%
group_by(ssid,Alexithymia, mediansplit_ground_valence, timebin2)%>%
ggplot(aes(x = timerezero3, y = pup_basCor))+
stat_smooth(aes(group= mediansplit_ground_valence, color = mediansplit_ground_valence), fun = mean,geom = "line",
se = F, size = 1.5)+
# stat_smooth(aes(group=ground_valence_lab, color = ground_valence_lab), size = 3)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
xlim(0,6)
test<- cor.test(db_2021_pupil_summ$hr_interp,db_2021_pupil_summ$pup_basCor)
test$p.value
tmp.df4_full_stim_downs_jun2021_with_beh$ssid_ground_valence<- paste0(tmp.df4_full_stim_downs_jun2021_with_beh$ssid, paste0(tmp.df4_full_stim_downs_jun2021_with_beh$ground_arousal_lab))
tmp.df4_full_stim_downs_jun2021_with_beh %>%
subset(!is.na(self_arousal_lab))%>%
db_full4new_stim_screen_pupil_nopract
group_by(ssid,Alexithymia, ground_valence_lab, timebin2)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor)$estimate)%>%
mutate(pcortest = cor.test(arousal_c, pup_basCor)$p.value)%>%
group_by(ssid,Alexithymia, self_arousal_lab, timebin2)%>%
summarise_if(is.numeric, mean, na.rm = TRUE) %>%
ggplot(aes(x = timerezero3, y = cortest))+
stat_smooth(aes(group= self_arousal_lab, color = self_arousal_lab), fun = mean,geom = "line",
se = F, size = 1.5)+
theme_classic()+
ylab("Pupil size (z)")+
xlab("Time (s)")+
# p$graphstyle+
scale_color_brewer(palette = "Dark2")+
geom_hline(yintercept = .05, linetype = "dashed")+
xlim(0,6)
# does arousing stimuli impairs appraisal
tmp.df4_full_stim_downs_jun2021_with_beh %>%
ggplot(aes(ground_arousal_lab, BRIGHTNESS))+
geom_boxplot()+
geom_point()+
# stat_summary(geom = 'boxplot')+
facet_grid(~mediansplit_self_valence)
db_full4new_stim_screen_pupil_nopract %>%
subset(pupil_outlier == FALSE & arousal_outler == FALSE & !is.na(Alexithymia) & ssid!= 610)%>%
# group_by(ssid,Alexithymia, is_valence_high)%>%
group_by(ssid,Alexithymia, mediansplit_self_valence)%>%
mutate(cortest = cor.test(arousal_c, pup_basCor)$estimate)%>%
group_by(ssid,Alexithymia, mediansplit_self_valence, self_arousal_lab)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_self_valence, cortest, color = mediansplit_self_valence))+
geom_bar(stat="summary", fun.y = "mean")+
geom_jitter(width = .1, alpha = .1)+
stat_summary( geom = 'pointrange')+
# stat_summary(aes(group = ssid), geom = 'line')+
ylab("R pupil vs self report arousal")+
# ggpubr::stat_compare_means(paired = TRUE)+
# ggpubr::stat_compare_means(comparisons = my_comparisons, paired = TRUE)
facet_grid(~self_arousal_lab)
SCR
unique(db_full4new_stim_screen_pupil_nopract$ssid)
View(flag_pos_neg)
db_full4new_stim_screen_pupil_nopract$mediansplit_self_arousal <- if_else(db_full4new_stim_screen_pupil_nopract$arousal> median(db_full4new_stim_screen_pupil_nopract$arousal, na.rm = TRUE), "High", "Low")
db_full4new_stim_screen_pupil_nopract$mediansplit_self_arousal_thissample <- if_else(db_full4new_stim_screen_pupil_nopract$arousal> median(db_full4new_stim_screen_pupil_nopract$ArousalMeanThisSample, na.rm = TRUE), "High", "Low")
unique(db_full4new_stim_screen_pupil_nopract2$ssid)
db_full4new_stim_screen_pupil_nopract_nt<- subset(db_full4new_stim_screen_pupil_nopract, ssid_num<500)
nrow(db_full4new_stim_screen_pupil_nopract_nt)
# 2233
# nrow(left_join(db_full4new_stim_screen_pupil_nopract_nt, flag_pos_neg))
db_full4new_stim_screen_pupil_nopract_nt<- left_join(db_full4new_stim_screen_pupil_nopract_nt, flag_pos_neg)
unique(db_full4new_stim_screen_pupil_nopract_nt$stimDescription)
db_full4new_stim_screen_pupil_nopract_nt %>%
subset(ssid_num< 500)%>%
subset(pp_arousal_outler == FALSE)%>%
subset( arousal_outler == FALSE )%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid)%>%
mutate(BIO_CDA.SCR_z = scale((BIO_CDA.SCR))[,1])%>%
ungroup()%>%
group_by(ssid,cor_pos_neg_diff_lab, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_self_valence, BIO_CDA.SCR_z))+
stat_summary(geom = 'pointrange')+
# geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
geom_jitter(width = .2, alpha = .2)+
stat_summary(aes(group = ssid), geom = 'line', color = "gray", alpha = .1)+
# geom_boxplot(alpha = .1)+
# facet_grid(~cor_pos_neg_diff_lab)+
ggpubr::stat_compare_means()
BIO_CDA.ISCR_z
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid)%>%
mutate(BIO_TTP.AmpSum_z = scale(BIO_TTP.AmpSum, center = TRUE, scale = TRUE)[,1])%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, BIO_TTP.AmpSum_z))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid,mediansplit_sample_valence2)%>%
# mutate(BIO_TTP.AmpSum_z = scale(BIO_TTP.AmpSum, center = TRUE, scale = TRUE)[,1])%>%
# summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal, BIO_CDA.ISCR_z))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
facet_grid(~mediansplit_sample_valence2)
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid,mediansplit_sample_valence2)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, BIO_CDA.PhasicMax_z, color =mediansplit_sample_valence2))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid,ground_arousal_lab)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal_c, BIO_CDA.PhasicMax_z, color =ground_arousal_lab))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
scr model
unique(db_full4new_stim_screen_pupil_nopract_nt$condition)
pupil_arousal_findings$arousal_scr <- lmer(log(BIO_CDA.SCR+.1) ~ arousal_c*TASc +(1|ssid) + (1|stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt,
pp_arousal_outler == FALSE &
mediansplit_self_valence == "More positive"))
summary(pupil_arousal_findings$arousal_scr)
anova(pupil_arousal_findings$arousal_phas_max)
BIO_CDA.PhasicMax
pupil_arousal_findings$arousal_scr <- lmer(BIO_CDA.PhasicMax_z ~ valence_c +(1+arousal_c|ssid),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt,
pp_arousal_outler == FALSE))
# mediansplit_self_valence == "More positive"))
summary(pupil_arousal_findings$arousal_scr)
anova(pupil_arousal_findings$arousal_phas_max)
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid, cor_pos_neg_diff_lab)%>%
ggplot(aes(cor_pos_neg_diff_lab, TAS))+
geom_point()+
stat_summary(geom = 'pointrange')
summary(pupil_arousal_findings\(arousal_scr) anova(pupil_arousal_findings\)arousal_phas_max)
test<- subset(db_full4new_stim_screen_pupil_nopract, pp_arousal_outler == FALSE & ssid == 310) test\(Alexithymia table(test\)mediansplit_self_valence)
try the anova grouping
afex::aov_ez(data = (db_full4new_stim_screen_pupil_nopract %>%
subset(pp_arousal_outler == FALSE)%>%
# subset(is_scr_nonresponder == FALSE )%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid, mediansplit_ground_valence)%>%
# group_by(ssid, Alexithymia,mediansplit_self_arousal, mediansplit_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)),
id = "ssid",
between = NULL,
within = c("mediansplit_ground_valence"),
dv = "BIO_CDA.SCR_z")
colnames(db_full4new_stim_screen_pupil_nopract)
ggcorrplot::ggcorrplot(cor(db_full4new_stim_screen_pupil_nopract[,c(19,115,125:128,27,26)], use = "complete"))
BIO_CDA.SCR_z
indovidual plots
facet_hist_scr<- db_full4new_stim_screen_pupil_nopract %>%
subset(ssid > 303)%>%
subset(arousal_outler == FALSE )%>%
subset(!is.na(Alexithymia))%>%
ggplot(aes(log1p(BIO_CDA.SCR+1)))+
geom_histogram(bins = )+
facet_wrap(~ssid)
what’s up with non responders
312
318 only one rspinse?
320
321
327
329
332
335 (only one response)
342
343
600
603
606 (only one response)
608
900
56- 15
that would leave us with 41 people
unique(db_full4new_stim_screen_pupil_nopract$ssid)
range(db_full4new_stim_screen_pupil_nopract$BIO_CDA.SCR, na.rm = TRUE)
mean(db_full4new_stim_screen_pupil_nopract$BIO_CDA.SCR, na.rm = TRUE)
sd(db_full4new_stim_screen_pupil_nopract$BIO_CDA.SCR, na.rm = TRUE)
db_full4new_stim_screen_pupil_nopract%>%
ggplot(aes(BIO_CDA.SCR))+
geom_histogram(bins = 500)
xlim(0,.01)
db_full4new_stim_screen_pupil_nopract%>%
subset(ssid == 312)%>%
ggplot(aes(BIO_CDA.AmpSum))+
geom_histogram(bins = 500)+
xlim(0,.05)
db_full4new_stim_screen_pupil_nopract$is_scr_nonresponder<- if_else(db_full4new_stim_screen_pupil_nopract$BIO_CDA.AmpSum< .1, TRUE, FALSE)
db_full4new_stim_screen_pupil_nopract %>%
subset(ssid > 303)%>%
subset(arousal_outler == FALSE )%>%
subset(!is.na(Alexithymia))%>%
ggplot(aes(log1p(BIO_CDA.SCR+1)))+
geom_histogram(bins = )+
facet_grid(~is_scr_nonresponder)
facet_wrap(~ssid)
db_full4new_stim_screen_pupil_nopract%>%
group_by(ssid,is_scr_nonresponder)%>%
mutate(scr_nonresp_prop = n())%>%
group_by(ssid)%>%
mutate(scr_nonresp_prop = scr_nonresp_prop/n())%>%
ggplot(aes(as.factor(ssid), scr_nonresp_prop))+
geom_bar(stat="summary", fun.y = "mean", alpha = .2, width = .5)
# test<- subset(db_full4new_stim_screen_pupil_nopract, ssid == 321)
table(db_full4new_stim_screen_pupil_nopract_nt$is_scr_nonresponder)
db_full4new_stim_screen_pupil_nopract_nt %>%
subset(is_scr_nonresponder != FALSE)%>%
subset(pp_arousal_outler == FALSE)%>%
subset(!ssid %in% c("304","321", "323", "318","339","331","325"))%>%
# subset( arousal_outler == FALSE )%>%
subset(!is.na(Alexithymia))%>%
group_by(ssid)%>%
mutate(BIO_CDA.SCR_z = scale(log1p(BIO_CDA.PhasicMax +.1))[,1])%>%
# ungroup()%>%
group_by(ssid, Alexithymia,mediansplit_sample_arousal2, mediansplit_sample_valence2)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
# group_by(ssid)%>%
# mutate(SCR_trend = BIO_CDA.SCR_z[mediansplit_ground_arousal == "Higher arousal"] -
# BIO_CDA.SCR_z[mediansplit_ground_arousal == "Lower arousal"])
# mutate(trendscr = if_else(SCR_trend> 0, "high to high", "high to low"))
# group_by(ssid, Alexithymia,mediansplit_ground_arousal,trendscr)%>%
# summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_sample_arousal2, BIO_CDA.SCR_z))+
stat_summary(geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line')+
# geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
geom_jitter(width = .2, alpha = .2)
facet_grid(~mediansplit_sample_valence2)
# geom_boxplot(alpha = .1)
# geom_text(aes(label = ssid))
facet_grid(~trendscr)
# ylim(-1,1)
304, 318, 339, 331,325
scr_models<- list()
db_full4new_stim_screen_pupil_nopract_nt %>%
subset(is_scr_nonresponder == FALSE)%>%
subset(pp_arousal_outler == FALSE)%>%
subset(!ssid %in% c("304","321", "323", "318","339","331","325"))
# subset( arousal_outler == FALSE )%>%
db_full4new_stim_screen_pupil_nopract_nt_scr_excluding_atypical<- db_full4new_stim_screen_pupil_nopract_nt%>%
subset(!ssid %in% c("304","321", "323", "318","339","331","325"))
# subset(is_scr_nonresponder == FALSE)%>%
group_by(ssid)%>%
mutate(BIO_CDA.PhasicMax_z = scale(BIO_CDA.PhasicMax, center = TRUE, scale = TRUE)[,1])%>%
mutate(valence_z = scale(valence, center = TRUE, scale = TRUE)[,1])%>%
mutate(arousal_z = scale(arousal, center = TRUE, scale = TRUE)[,1])
scr_models$scr_excluding_atypical<- lmer(log(BIO_CDA.PhasicMax+.1) ~ valence_z + arousal_z+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = db_full4new_stim_screen_pupil_nopract_nt_scr_excluding_atypical)
scr_models$scr_excluding_atypical<- lmer(log(BIO_CDA.PhasicMax+.1) ~ valence_c + arousal_c+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = db_full4new_stim_screen_pupil_nopract_nt)
# subset(!ssid %in% c("304","321", "323", "318","339","331","325"))%>%
subset(is_scr_nonresponder != FALSE))
summary(scr_models$scr_excluding_atypical)
(db_full4new_stim_screen_pupil_nopract_nt%>%
subset(!ssid %in% c("304","321", "323", "318","339","331","325"))))
summary(scr_models$scr_excluding_atypical)
db_full4new_stim_screen_pupil_nopract %>%
subset(is_scr_nonresponder == FALSE)%>%
subset(pp_arousal_outler == FALSE)%>%
subset( arousal_outler == FALSE )%>% subset(!is.na(Alexithymia))%>% group_by(ssid)%>% mutate(BIO_CDA.SCR_z = scale(log1p(BIO_CDA.PhasicMax +.1))[,1])%>% mutate(arousal_z = scale(arousal +.1))%>% ungroup()%>% # group_by(ssid, Alexithymia,mediansplit_self_arousal)%>% # summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(arousal_z, BIO_CDA.SCR_z))+ geom_point()+ # geom_smooth(aes(group = ssid),method = ‘lm’, se = F)+ geom_smooth(method = ‘lm’, se = F)+ facet_grid(~ground_arousal_lab)
# geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
geom_jitter(width = .2, alpha = .2)+ ylim(-1,1)
# panel for many folks db_full4new_stim_screen_pupil_nopract %>% # subset(ssid == 314)%>% group_by(ssid)%>% mutate(BIO_CDA.SCR_z = scale(log1p(BIO_CDA.PhasicMax +.1))[,1])%>% mutate(arousal_z = scale(arousal +.1))%>% ggplot(aes(arousal_z,BIO_CDA.SCR_z, color =mediansplit_ground_valence , shape =mediansplit_ground_arousal))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ facet_wrap(~ssid)+ ggpubr::stat_cor()
db_full4new_stim_screen_pupil_nopract %>%
# subset(ssid == 314)%>% group_by(ssid)%>% mutate(BIO_CDA.SCR_z = scale(log1p(BIO_CDA.PhasicMax +.1))[,1])%>% mutate(arousal_z = scale(arousal +.1))%>% ggplot(aes(pup_basCor,BIO_CDA.SCR_z))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ facet_wrap(~ssid)+ ggpubr::stat_cor()
db_full %>%
# subset(ssid == 314)%>% group_by(ssid)%>% mutate(BIO_Mean_HR = scale(BIO_Mean_HR, scale = FALSE)[,1])%>% mutate(arousal_z = scale(arousal +.1))%>% ggplot(aes(BIO_Mean_HR,log1p(BIO_CDA.PhasicMax+.1)))+ geom_point()+ geom_smooth(aes(group = ssid),method = ‘lm’, se = F) facet_wrap(~ssid)+ ggpubr::stat_cor()
Let’s try some 3 d visualisations continue here
db_full4new_stim_screen_pupil_nopract_nt %>%
group_by(ssid, mediansplit_ground_arousal, mediansplit_ground_valence,scr_utl)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
subset(scr_utl == "notoutlier")%>%
ggplot(aes(mediansplit_ground_arousal , BIO_CDA.PhasicMax_z))+
geom_jitter(alpha = .1, width = .1)+
stat_summary(geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = "line", alpha = .1)+
facet_grid(~mediansplit_ground_valence)
db_full4new_stim_screen_pupil_nopract_nt%>%
ggplot(aes(BIO_CDA.PhasicMax_z))+
geom_histogram()
db_full4new_stim_screen_pupil_nopract_nt<- db_full4new_stim_screen_pupil_nopract_nt%>%
mutate(scr_utl = if_else(BIO_CDA.PhasicMax_z > 5, "outlier", "notoutlier"))
# + arousal_c
scr_models$scr_excluding_atypical<- lmer(log(BIO_CDA.AmpSum_collapsed+.1) ~ arousal_c*valence_c * TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, scr_utl == "notoutlier"))
summary(scr_models$scr_excluding_atypical)
plot(scr_models$scr_excluding_atypical)
interactions::interact_plot(scr_models$scr_excluding_atypical, pred = arousal_c, modx = valence_c, mod2 = TASc)
db_full4new_stim_screen_pupil_nopract_nt%>%
ggplot(aes())
scr_models$scr1<- lmer(log(BIO_CDA.PhasicMax_collapsed+.1) ~ arousal_c*valence_c * TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, scr_utl == "notoutlier"))
summary(scr_models$scr1)
scr_models$scr1.2<- lmer(log1p(BIO_CDA.PhasicMax+.1) ~ TASc*arousal_c * valence_c+
(1 | ssid)+
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, Group == "NT", !is.na(Alexithymia)))
unique(db_full4new_stim_screen_pupil_nopract$ssid)
summary(scr_models$scr1.2)
db_full4new_stim_screen_pupil_nopract %>%
group_by(ssid,Group)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
subset(Group == "NT")%>%
ggplot(aes(TAS))+
geom_histogram()
interactions::interact_plot(scr_models$scr1, pred = arousal_c, modx = valence_c, mod2 = TASc)
scr_models$scr1.1<- lmer(CDA.PhasicMax ~ arousal_c*valence_c * TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, scr_utl == "notoutlier"))
summary(scr_models$scr1.1)
interactions::interact_plot(scr_models$scr1.1, pred = arousal_c, modx = valence_c, mod2 = TASc)
scr_models$scr2<- lmer(BIO_CDA.ISCR_collapsed ~ arousal_c*valence_c *TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, scr_utl == "notoutlier"))
summary(scr_models$scr2)
interactions::interact_plot(scr_models$scr2, pred = arousal_c, modx = valence_c)
scr_models$scr2<- lmer(BIO_CDA.SCR_collapsed ~ arousal_c* valence_c *TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract, Group = "NT"))
summary(scr_models$scr2)
interactions::interact_plot(scr_models$scr2, pred = arousal_c, modx = valence_c)
# the effect of pupil is the opposite on scr
scr_models$scr3<- lmer(BIO_CDA.ISCR_collapsed ~ arousal_c * valence_c * TASc+
(1| ssid) +
(1 | stimIAPS),
REML = FALSE,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, scr_utl == "notoutlier"))
summary(scr_models$scr3)
interactions::interact_plot(scr_models$scr2, pred = arousal_c, modx = valence_c, mod2 = TASc)
# the effect of pupil is the opposite on scr
check scr on within individuals
lm_objtest<- lm(BIO_CDA.PhasicMax_z ~ arousal * valence, data = db_full4new_stim_screen_pupil_nopract_nt)
lm_objtest_summ<-summary(lm_objtest)
lm_objtest_summ$coefficients
db_full4new_stim_screen_pupil_nopract_nt
lm_objtest[["coefficients"]][[2]]
lm_objtest[["coefficients"]][["arousal"]]
lm_objtest[["coefficients"]][["valence"]]
regression_df <- data.frame(ssid= rep(NA, 50), Estimate_arousal= rep(NA, 50),
Estimate_valence= rep(NA, 50),
Estimate_int= rep(NA, 50),
p_arousal= rep(NA, 50),
p_valence= rep(NA, 50),
p_int= rep(NA, 50))
lm_ind_summary$coefficients[[14]]
ssid<- unique(db_full4new_stim_screen_pupil_nopract_nt$ssid)
db_full4new_stim_screen_pupil_nopract_nt<- db_full4new_stim_screen_pupil_nopract_nt%>%
group_by(ssid)%>%
mutate(arousal_z_ssid = scale(arousal - mean(arousal, na.rm = TRUE))[,1],
valence_z_ssid = scale(valence - mean(valence, na.rm = TRUE))[,1])
i = 1
rm(b)
# debug
ssid_tes<- unique(db_full4new_stim_screen_pupil_nopract_nt$ssid_num)
table(is.na(db_full4new_stim_screen_pupil_nopract_nt$BIO_CDA.PhasicMax_z))
lm_ind <- lm(BIO_CDA.PhasicMax_z ~ arousal_z_ssid *valence_z_ssid,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, !is.na(BIO_CDA.PhasicMax_z) &
ssid_num == ssid_tes[10]))
subset(db_full4new_stim_screen_pupil_nopract_nt, !is.na(BIO_CDA.PhasicMax_z) &
ssid_num == ssid_tes[10])
i = 1
rm(b)
for (b in 5:length(ssid_tes)) {
# for (s in 1:length(nsim)) {
message(sprintf("$$$$$RUNING lmer for ssid %i", ssid_tes[b]))
# db_of7_new_JEFFE$VideoType_contrast_sample<- sample((rep(c(-.5, .5), each = 1920)), replace = FALSE)
#run the model on the current time bin and simulation sumber
lm_ind <- lm(BIO_CDA.PhasicMax_z ~ arousal_z_ssid *valence_z_ssid,
data = subset(db_full4new_stim_screen_pupil_nopract_nt, !is.na(BIO_CDA.PhasicMax_z) &
mediansplit_ground_valence == "More negative"&
ssid_num == ssid_tes[b]))
#store results from the simulation
lm_ind_summary<- summary(lm_ind)
regression_df[i,1]<- ssid_tes[b] #save ssid
regression_df[i,2]<- lm_ind_summary$coefficients[[2]] # arousal beta
regression_df[i,3]<-lm_ind_summary$coefficients[[3]] # valence beta
regression_df[i,4]<-lm_ind_summary$coefficients[[4]] # inyteraction beta
regression_df[i,4]<-lm_ind_summary$coefficients[[4]]
regression_df[i,5]<- lm_ind_summary$coefficients[[14]]
regression_df[i,6]<- lm_ind_summary$coefficients[[15]]
regression_df[i,7]<- lm_ind_summary$coefficients[[16]]
lm_ind_summary$coefficients[[14]]
# simulated_clusters_JEFFE[i,6]<- nsim[s] #store simulation ount
# timecourse_result_df_neg[i,5] <-ifelse(length(lmer_bin_pup_summary$optinfo$conv$lme4$message)
# != 0,
# lmer_bin_pup_summary$optinfo$conv$lme4$message, 'pass')
i = i+1
}
View(regression_df)
lm_ind_summary$coefficients[[4]]
# whether I use ground valence, self valemce or this sample average valence, I get the same patterns
timecourse_result_df_neg%>%
ggplot(aes(timebins, t))+
geom_line(size = 2)+
geom_line(aes(y = p), linetype = "dashed", size = 2)+
geom_hline(yintercept = .1, color = 'red', size = 1.5)
t.test(regression_df$Estimate_arousal)
ssid# just positive
regression_df <- data.frame(ssid= rep(NA, 50), Estimate_arousal= rep(NA, 50),
Estimate_valence= rep(NA, 50),
Estimate_int= rep(NA, 50),
p_arousal= rep(NA, 50),
p_valence= rep(NA, 50),
p_int= rep(NA, 50))
scatter3D(x, y, z, clab = c("Sepal", "Width (cm)"))
db_full4new_stim_screen_pupil_nopract_nt
install.packages("plot3D")
install.packages("misc3d")
library(misc)
plot3D::scatter3D(db_full4new_stim_screen_pupil_nopract_nt$pup_basCor,
db_full4new_stim_screen_pupil_nopract_nt$arousal_c,
db_full4new_stim_screen_pupil_nopract_nt$valence_c)
install.packages("plot3D", dependencies = TRUE)
install.packages("misc3d", repo = 'https://mac.R-project.org')
install.packages(c("rgl", "car"))
library(car)
install.packages("car", dependencies = TRUE)
car::scatter3d(db_full4new_stim_screen_pupil_nopract_nt$arousal_c,
db_full4new_stim_screen_pupil_nopract_nt$pup_basCor,
db_full4new_stim_screen_pupil_nopract_nt$valence_c,
fit = "smooth"
# point = FALSE,
# surface = FALSE,
# point.col = ""
)
gg = ggplot(db_full4new_stim_screen_pupil_nopract_nt, aes(BIO_CDA.PhasicMax_z, arousal_c)) + stat_density_2d(aes(fill = stat(db_full4new_stim_screen_pupil_nopract_nt$valence_c)), geom = “polygon”, n = 100,bins = 10,contour = TRUE) + # facet_wrap(clarity~.) + scale_fill_viridis_c(option = “A”)
rayshader::plot_gg(gg,multicore=TRUE,width=5,height=5,scale=250)
scr<- db_full4new_stim_screen_pupil_nopract_nt\(BIO_CDA.PhasicMax_z arousal<- db_full4new_stim_screen_pupil_nopract_nt\)arousal_c
valence = db_full4new_stim_screen_pupil_nopract_nt$valence_c
gg = ggplot(db_full4new_stim_screen_pupil_nopract_nt, aes(BIO_CDA.PhasicMax_z, arousal_c)) + stat_density_2d(aes(fill = stat(valence_c)), geom = “polygon”, # n = 100,bins = 10, contour = TRUE) + # facet_wrap(clarity~.) + scale_fill_viridis_c(option = “A”) rayshader::plot_gg(gg,multicore=TRUE,width=5,height=5,scale=250) gg #No lines pp_nolines = ggplot(db_full4new_stim_screen_pupil_nopract_nt, aes(x=BIO_CDA.PhasicMax_z, y=arousal_c)) + geom_point(aes(color = valence_c)) scale_fill_viridis_c(a)
rayshader::plot_gg(pp_nolines, width = 4, height = 4, scale = 300, multicore = TRUE) pp_nolines
?scatter3d scatter3d(x = arousal, y = valence, z = scr, fit = “smooth”,
# surface = FALSE,
point.col = "blue",
# point
groups = as.factor(db_full4new_stim_screen_pupil_nopract_nt$mediansplit_sample_valence2),
ellipsoid = FALSE)
scatter3d(x = db_full4new_stim_screen_pupil_nopract_nt\(pup_basCor, y = db_full4new_stim_screen_pupil_nopract_nt\)BIO_CDA.PhasicMax_z, z = db_full4new_stim_screen_pupil_nopract_nt, fit = “smooth”,
# surface = FALSE,
point.col = "blue",
# point
groups = as.factor(db_full4new_stim_screen_pupil_nopract_nt$mediansplit_ground_valence),
ellipsoid = FALSE)
library(viridisLite) install.packages(“viridis”) library(viridis) deathgg = ggplot(db_full4new_stim_screen_pupil_nopract_nt) + geom_tile(aes(x=arousal_c,y=pup_basCor,fill=valence_c))+ # scale_x_continuous(“Year”,expand=c(0,0),breaks=seq(1900,2010,10)) + # scale_y_continuous(“Age”,expand=c(0,0),breaks=seq(0,100,10),limits=c(0,100)) + scale_fill_viridis() # ggtitle(“Death Probability vs Age and Year for the USA”) + # labs(caption = “Data Source: US Dept. of Social Security”)
rayshader:: plot_gg(deathgg, multicore=TRUE) height=5,width=6,scale=500
heart rate
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuXG5cblxuXG5cbnVuaXF1ZShkYl9mdWxsNm5ldyRCaW9fTWVhbl9IUilcbnVuaXF1ZShkYl9mdWxsNm5ldyRCaW9fTWVhbl9IUl9maXgpXG5cblxuVmlldyhkYl9mdWxsNm5ldylcblxuZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdFxuICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JVxuICAjIHN1YnNldChzc2lkID09IDMxNCklPiVcbiAgICBncm91cF9ieShzc2lkKSU+JVxuICAgIG11dGF0ZShCSU9fQ0RBLlNDUl96ID0gc2NhbGUobG9nMXAoQklPX0NEQS5QaGFzaWNNYXggKy4xKSlbLDFdKSU+JVxuICAgIG11dGF0ZShhcm91c2FsX3ogPSBzY2FsZShhcm91c2FsICsuMSkpJT4lXG4gIGdncGxvdChhZXMoYXJvdXNhbF96LEJJT19DREEuU0NSX3osIGNvbG9yID1tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSAsIHNoYXBlID1tZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCkpK1xuICAgIGdlb21fcG9pbnQoKStcbiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpK1xuICAgIGZhY2V0X3dyYXAofnNzaWQpK1xuICAgIGdncHVicjo6c3RhdF9jb3IoKVxuXG5cbmBgYCJ9 -->
```r
unique(db_full6new$Bio_Mean_HR)
unique(db_full6new$Bio_Mean_HR_fix)
View(db_full6new)
db_full4new_stim_screen_pupil_nopract
db_full4new_stim_screen_pupil_nopract %>%
# subset(ssid == 314)%>%
group_by(ssid)%>%
mutate(BIO_CDA.SCR_z = scale(log1p(BIO_CDA.PhasicMax +.1))[,1])%>%
mutate(arousal_z = scale(arousal +.1))%>%
ggplot(aes(arousal_z,BIO_CDA.SCR_z, color =mediansplit_ground_valence , shape =mediansplit_ground_arousal))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
facet_wrap(~ssid)+
ggpubr::stat_cor()
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuXG4jIGtlZXAgc3RpbSBhbmQgYW5kIGZpeGF0aW9uXG5cbnVuaXF1ZShkYl9mdWxsNm5ldyRzY3JlZW5jb250ZW50KVxudW5pcXVlKGRiX2Z1bGw2bmV3JHNjcmVlbmNvbnRlbnRfbm8pXG5kYl9mdWxsNm5ld19ocl9maXhfc3RpbTwtIHN1YnNldChkYl9mdWxsNm5ldywgc2NyZWVuY29udGVudF9ubyA8MylcblZpZXcoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW0pXG4jIGZpeGF0aW9uXCIgICAgXCJzdGltXCIgXG5cbiMga2VlcCBjb250cm9sc1xudW5pcXVlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltJHNzaWQpXG5kYl9mdWxsNm5ld19ocl9maXhfc3RpbSRzc2lkX251bSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihkYl9mdWxsNm5ld19ocl9maXhfc3RpbSRzc2lkKSlcblxuXG5cbmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250PC0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltLCBHcm91cCA9PSBcIk5UXCIpXG51bmlxdWUoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQkc3NpZF9udW0pXG5cbmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250PC0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltLCBzc2lkX251bT4gMzAzKVxudW5pcXVlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250JHNzaWQpXG5cbiMgSFIgZGlmZmVyZW5jZXNcbmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250JEJpb19NZWFuX0hSX2ZpeDwtIGlmX2Vsc2UoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQkc2NyZWVuY29udGVudF9ubyA9PTEsIGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250JEJpb19NZWFuX0hSLCBOVUxMKVxuXG5WaWV3KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250KVxuXG5saWJyYXJ5KGRwbHlyKVxubGlicmFyeSh0aWR5dmVyc2UpXG5kYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDE8LSBkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udCAlPiVcbiAgZ3JvdXBfYnkoc3NpZCwgdE5vKSAlPiVcbiAgYXJyYW5nZShzc2lkLCB0Tm8sc2NyZWVuY29udGVudF9ubyklPiVcbiAgZmlsbChCaW9fTWVhbl9IUl9maXgsIC5kaXJlY3Rpb24gPSBcImRvd25cIiklPiVcbiAgc3Vic2V0KHNjcmVlbmNvbnRlbnRfbm8gPT0gMilcblxuVmlldyhkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEpXG5cbmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MTwtIGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSAlPiVcbiAgbXV0YXRlKEJpb19NZWFuX0hSX2RpZiA9IEJpb19NZWFuX0hSIC0gQmlvX01lYW5fSFJfZml4KVxuIyAyIDFcbnN0aW0gLSBmaXhcbmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSU+JVxuICBnZ3Bsb3QoYWVzKEJpb19NZWFuX0hSX2RpZikpK1xuICBnZW9tX2hpc3RvZ3JhbSgpXG5cbj9zY2F0dGVyM2QgXG5cblxuZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lXG4gIHN1YnNldCghaXMubmEocHVwX2Jhc0NvcikpJT4lXG4gICBzdWJzZXQoIWlzLm5hKEJJT19DREEuUGhhc2ljTWF4X3opKSU+JVxuICBzdWJzZXQoIWlzLm5hKEJpb19NZWFuX0hSX2RpZikpXG5cblxuZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxPC0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lXG4gIGdyb3VwX2J5KHNzaWQpJT4lXG4gIG11dGF0ZShCSU9fQ0RBLlBoYXNpY01heF96PSBzY2FsZShCSU9fQ0RBLlBoYXNpY01heCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0pXG5cbnNjYXR0ZXIzZCh4ID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJHB1cF9iYXNDb3IsIFxuICAgICAgICAgIHkgPSBkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEkQklPX0NEQS5QaGFzaWNNYXhfeiwgXG4gICAgICAgICAgeiA9IGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWYsIFxuICAgICAgICAgIGZpdCA9IFwic21vb3RoXCIsXG4gICAgICAgICAgXG4gICAgICAgICAgc3VyZmFjZSA9IEZBTFNFLFxuICAgICAgICAgIHBvaW50LmNvbCA9IFwiYmx1ZVwiLFxuICAgICAgICAgICMgcG9pbnRcbiAgICAgICAgICBncm91cHMgPSBhcy5mYWN0b3IoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsKSxcbiAgICAgICAgICBlbGxpcHNvaWQgPSBUUlVFKVxuXG5cblxuY29yKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MVssYyhcInB1cF9iYXNDb3JcIiwgXCJCSU9fQ0RBLlBoYXNpY01heF96XCIsXCJCaW9fTWVhbl9IUl9kaWZcIildLCB1c2UgPSBcImNvbXBsZXRlXCIpXG5cblxuXG5kYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiVcbiAgZ3JvdXBfYnkoc3NpZCxtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiVcbiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiVcbiAgZ2dwbG90KGFlcyhwdXBfYmFzQ29yLEJJT19DREEuUGhhc2ljTWF4X3osIGNvbG9yPSBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpK1xuICBnZW9tX3BvaW50KCkrXG4gIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrXG4gIHlsaW0oMCwuNCkrXG4gIGdncHVicjo6c3RhdF9jb3IoKVxuXG5cblxuZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lXG4gICMgZ3JvdXBfYnkoc3NpZCklPiVcbiAgIyBtdXRhdGUoQmlvX01lYW5fSFJfZGlmX3ogPSBzY2FsZShCaW9fTWVhbl9IUl9kaWYpKVxuICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JVxuICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JVxuICBnZ3Bsb3QoYWVzKHB1cF9iYXNDb3IsQmlvX01lYW5fSFJfZGlmX3osIGNvbG9yPSBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpK1xuICBnZW9tX3BvaW50KCkrXG4gIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrXG4gICMgeWxpbSgtNywyKStcbiAgZ2dwdWJyOjpzdGF0X2NvcigpXG5cblxuXG5kYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiVcbiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpJT4lXG4gICMgZ3JvdXBfYnkoc3NpZCklPiVcbiAgIyBtdXRhdGUoQmlvX01lYW5fSFJfZGlmX3ogPSBzY2FsZShCaW9fTWVhbl9IUl9kaWYpKVxuICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JVxuICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JVxuICBnZ3Bsb3QoYWVzKEJJT19DREEuUGhhc2ljTWF4X3osQmlvX01lYW5fSFJfZGlmLCBjb2xvcj0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKStcbiAgZ2VvbV9wb2ludCgpK1xuICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpK1xuICAjIHlsaW0oLTcsMikrXG4gIGdncHVicjo6c3RhdF9jb3IoKStcbiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpXG4gIFxuXG5gYGAifQ== -->
```r
# keep stim and and fixation
unique(db_full6new$screencontent)
unique(db_full6new$screencontent_no)
db_full6new_hr_fix_stim<- subset(db_full6new, screencontent_no <3)
View(db_full6new_hr_fix_stim)
# fixation" "stim"
# keep controls
unique(db_full6new_hr_fix_stim$ssid)
db_full6new_hr_fix_stim$ssid_num <- as.numeric(as.character(db_full6new_hr_fix_stim$ssid))
db_full6new_hr_fix_stim_nt<- subset(db_full6new_hr_fix_stim, Group == "NT")
unique(db_full6new_hr_fix_stim_nt$ssid_num)
db_full6new_hr_fix_stim_nt<- subset(db_full6new_hr_fix_stim, ssid_num> 303)
unique(db_full6new_hr_fix_stim_nt$ssid)
# HR differences
db_full6new_hr_fix_stim_nt$Bio_Mean_HR_fix<- if_else(db_full6new_hr_fix_stim_nt$screencontent_no ==1, db_full6new_hr_fix_stim_nt$Bio_Mean_HR, NULL)
View(db_full6new_hr_fix_stim_nt)
library(dplyr)
library(tidyverse)
db_full6new_hr_fix_stim_nt1<- db_full6new_hr_fix_stim_nt %>%
group_by(ssid, tNo) %>%
arrange(ssid, tNo,screencontent_no)%>%
fill(Bio_Mean_HR_fix, .direction = "down")%>%
subset(screencontent_no == 2)
View(db_full6new_hr_fix_stim_nt1)
db_full6new_hr_fix_stim_nt1<- db_full6new_hr_fix_stim_nt1 %>%
mutate(Bio_Mean_HR_dif = Bio_Mean_HR - Bio_Mean_HR_fix)
# 2 1
stim - fix
db_full6new_hr_fix_stim_nt1%>%
ggplot(aes(Bio_Mean_HR_dif))+
geom_histogram()
?scatter3d
db_full6new_hr_fix_stim_nt1%>%
subset(!is.na(pup_basCor))%>%
subset(!is.na(BIO_CDA.PhasicMax_z))%>%
subset(!is.na(Bio_Mean_HR_dif))
db_full6new_hr_fix_stim_nt1<- db_full6new_hr_fix_stim_nt1%>%
group_by(ssid)%>%
mutate(BIO_CDA.PhasicMax_z= scale(BIO_CDA.PhasicMax, center = TRUE, scale = TRUE)[,1])
scatter3d(x = db_full6new_hr_fix_stim_nt1$pup_basCor,
y = db_full6new_hr_fix_stim_nt1$BIO_CDA.PhasicMax_z,
z = db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif,
fit = "smooth",
surface = FALSE,
point.col = "blue",
# point
groups = as.factor(db_full6new_hr_fix_stim_nt1$mediansplit_ground_arousal),
ellipsoid = TRUE)
cor(db_full6new_hr_fix_stim_nt1[,c("pup_basCor", "BIO_CDA.PhasicMax_z","Bio_Mean_HR_dif")], use = "complete")
db_full6new_hr_fix_stim_nt1%>%
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(pup_basCor,BIO_CDA.PhasicMax_z, color= mediansplit_ground_valence))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ylim(0,.4)+
ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt1%>%
# group_by(ssid)%>%
# mutate(Bio_Mean_HR_dif_z = scale(Bio_Mean_HR_dif))
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(pup_basCor,Bio_Mean_HR_dif_z, color= mediansplit_ground_valence))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# ylim(-7,2)+
ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt1%>%
subset(!is.na(mediansplit_ground_valence))%>%
# group_by(ssid)%>%
# mutate(Bio_Mean_HR_dif_z = scale(Bio_Mean_HR_dif))
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(BIO_CDA.PhasicMax_z,Bio_Mean_HR_dif, color= mediansplit_ground_valence))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# ylim(-7,2)+
ggpubr::stat_cor()+
facet_grid(~mediansplit_ground_valence)
db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif_outl<- if_else(abs(db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif)>
(median(abs(db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif),na.rm = TRUE) + (4*(sd(abs(db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif), na.rm = TRUE)))), "outlier", "not outlier")
db_full6new_hr_fix_stim_nt1%>%
ggplot(aes(Bio_Mean_HR_dif))+
geom_histogram()+
facet_grid(~Bio_Mean_HR_dif_outl)
db_full6new_hr_fix_stim_nt1 %>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
subset(ssid_num<500)%>%
group_by(ssid)%>%
mutate(Bio_Mean_HR_dif_ssid = mean(Bio_Mean_HR_dif, na.rm = TRUE))%>%
group_by(ssid)%>%
# mutate(Bio_Mean_HR_dif_stim = mean(Bio_Mean_HR_dif, na.rm = TRUE))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(TASc, Bio_Mean_HR_dif))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt1 %>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
subset(ssid_num<500)%>%
# group_by(ssid)%>%
mutate(Bio_Mean_HR_dif = abs(Bio_Mean_HR_dif))%>%
group_by(ssid, stimIAPS)%>%
mutate(Bio_Mean_HR_dif_stim = abs(Bio_Mean_HR_dif))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(TASc, Bio_Mean_HR_dif))+
# geom_point()
geom_smooth(aes(group = stimIAPS, y =Bio_Mean_HR_dif_stim), method=lm, se=FALSE, colour = "gray40", alpha = .01,linetype="dashed", size = .2 )+
geom_smooth( method=lm, se=FALSE, linetype="dashed",
color="darkred", size = 2)+
stat_summary(geom = 'pointrange', pch = 1)+
# geom_point()+
# stat_summary(aes(group =ssid, y = Bio_Mean_HR_dif),method = "line",alpha = .1)+
# ggpubr::stat_cor()+
p$graphstyle+
xlab("Alexithymia (Z)")+
ylab("HR difference")+
p$graphstyle
hr_bio <- lmer(Bio_Mean_HR_dif ~ TASc *arousal_c + (1|ssid) + (1| stimIAPS),
REML = FALSE,
data = subset(db_full6new_hr_fix_stim_nt1, Bio_Mean_HR_dif_outl == "not outlier"))
interactions::interact_plot(hr_bio, pred = arousal_c, modx = TASc)
subset(db_full6new_hr_fix_stim_nt1, Bio_Mean_HR_dif_outl == "not outlier")
db_full6new_hr_fix_stim_nt1 %>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
group_by(ssid)%>%
mutate(cor_hrdif_ar = cor(Bio_Mean_HR_dif, arousal_c))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(TAS, cor_hrdif_ar))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
p$graphstyle
db_full6new_hr_fix_stim_nt1 %>%
subset(TAS<70)%>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
group_by(ssid,mediansplit_ground_valence)%>%
mutate(cor_hrdif_ar = cor(Bio_Mean_HR_dif, arousal_c))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_valence, cor_hrdif_ar))+
geom_jitter(alpha = .1, width = .1)+
stat_summary(geom = 'pointrange')
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
p$graphstyle
db_full6new_hr_fix_stim_nt1 %>% # subset(Bio_Mean_HR_dif_outl == “not outlier”)%>% group_by(ssid)%>% mutate(cor_hrdif_ar = cor(Bio_Mean_HR_dif, arousal_c))%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(TAS, cor_hrdif_ar))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt1<- db_full6new_hr_fix_stim_nt1%>%
group_by(stimIAPS)%>%
mutate(ValenceMeanThisSample = mean(valence, na.rm = TRUE),
ArousalMeanThisSample = mean(arousal, na.rm = TRUE))
db_full6new_hr_fix_stim_nt1<- db_full6new_hr_fix_stim_nt1%>%
ungroup()%>%
mutate(mediansplit_ground_valence = if_else(ValenceMean >=
median(ValenceMean,
na.rm = TRUE), "More positive", "More negative"))%>%
mutate(mediansplit_ground_arousal = if_else(ArousalMean >=
median(ArousalMean,
na.rm = TRUE), "High", "Low"))%>%
mutate(mediansplit_sample_valence2 = if_else(ValenceMeanThisSample >=
median(ValenceMeanThisSample,
na.rm = TRUE), "More positive", "More negative"))%>%
mutate(mediansplit_sample_arousal2 = if_else(ArousalMeanThisSample >=
median(ArousalMeanThisSample,
na.rm = TRUE), "High", "Low"))
db_full6new_hr_fix_stim_nt1%>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
subset(!is.na(mediansplit_ground_valence))%>%
group_by(ssid,mediansplit_ground_arousal, mediansplit_ground_valence,)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_arousal, Bio_Mean_HR_dif))+
geom_jitter(alpha = .2, width = .2)+
geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
stat_summary(geom = 'pointrange')+
# stat_smooth(aes(group = ssid), se = F, method = 'lm', alpha = .2)+
facet_grid(~mediansplit_ground_valence)
db_full6new_hr_fix_stim_nt1%>%
subset(!is.na(mediansplit_ground_valence))%>%
subset(Bio_Mean_HR_dif_outl== "not outlier")%>%
group_by(ssid, mediansplit_ground_arousal,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_arousal, Bio_Mean_HR_dif, fill = mediansplit_ground_valence))+
geom_jitter(alpha = .2, width = .2)+
geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
stat_summary(geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', alpha = .2)+
facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_compare_means()
# p$graphstyle+
scale_fill_brewer(palette = "Dark2")+
# stat_smooth(aes(group = ssid), se = F, method = ‘lm’, alpha = .2)
db_full6new_hr_fix_stim_nt1%>% subset(!is.na(mediansplit_ground_valence))%>% subset(Bio_Mean_HR_dif_outl!= “outlier”)%>% group_by(ssid, mediansplit_ground_arousal,mediansplit_ground_valence)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(mediansplit_ground_arousal, Bio_Mean_HR_dif))+ geom_jitter(alpha = .2, width = .2)+ geom_bar(stat=“summary”, fun.y = “mean”, alpha = .2)+ stat_summary(geom = ‘pointrange’)+ ggpubr::stat_compare_means()+ facet_grid(~mediansplit_ground_valence)
self
db_full6new_hr_fix_stim_nt1%>% subset(!is.na(mediansplit_ground_valence))%>% subset(Bio_Mean_HR_dif_outl!= “outlier”)%>% group_by(ssid, mediansplit_sample_arousal2,mediansplit_sample_valence2)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(mediansplit_sample_arousal2, Bio_Mean_HR_dif))+ geom_jitter(alpha = .2, width = .2)+ stat_summary(aes(group = ssid), geom = ‘line’, alpha = .1, size = .4, colour = “Black”) + # geom_bar(stat=“summary”, fun.y = “mean”, alpha = .2)+ stat_summary(geom = ‘pointrange’)+ ggpubr::stat_compare_means()+ facet_grid(~mediansplit_sample_valence2)
lmer( db_full6new_hr_fix_stim_nt1)
db_full6new_hr_fix_stim_nt1%>% group_by(ssid)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(arousal))+ geom_histogram()
# test - analyse just positive
hr_dif_models$arousal_val <- lmer(Bio_Mean_HR_dif ~ valence_c *arousal_c+
+ (1 | ssid) + (1|stimIAPS),
# (1|mediansplit_sample_arousal2),
REML = FALSE,
data = subset(db_full6new_hr_fix_stim_nt1, mediansplit_ground_valence == "More positive" & Bio_Mean_HR_dif_outl == "not outlier" & Group == "NT"))
summary(hr_dif_models$arousal_val)
unique(db_full6new_hr_fix_stim_nt1$ssid)
hr_dif_models$valfrom_hr <- lmer(valence_c ~ Bio_Mean_HR_dif* arousal_c+
+ (1 | ssid) + (1|stimIAPS),
# (1|mediansplit_sample_arousal2),
REML = FALSE,
data = subset(db_full6new_hr_fix_stim_nt1, mediansplit_ground_valence == "More positive" &
Bio_Mean_HR_dif_outl == "not outlier" & Group == "NT"))
arousal_c
summary(hr_dif_models$valfrom_hr)
interactions::interact_plot(hr_dif_models$valfrom_hr, pred = Bio_Mean_HR_dif, modx = arousal_c)
plot(hr_dif_models$arousal_val)
car::vif(hr_dif_models$arousal_val)
# valence_c arousal_c valence_c:arousal_c
# 1.767605 1.708642 1.070635
?step
?lmerTest::step()
lmerTest::step(hr_dif_models$arousal_val)
# favours valence
# check the response bias thing
db_full6new_hr_fix_stim_nt1 %>%
subset(!is.na(mediansplit_ground_valence))%>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
ggplot(aes(log10(arousal+10.5) ,Bio_Mean_HR_dif))+
# geom_point(alpha = .1)+
facet_grid(~mediansplit_ground_valence)+
geom_smooth(method = 'lm', se = F)+
ggside::geom_ysidedensity(aes(x=stat(density, fill = mediansplit_self_valence), alpha = .4))+
ggside::geom_xsidedensity(aes(y=stat(density, fill = mediansplit_self_valence), alpha = .4))
scatter3d(x = db_full6new_hr_fix_stim_nt1$valence_c,
y =db_full6new_hr_fix_stim_nt1$Bio_Mean_HR_dif, z =db_full6new_hr_fix_stim_nt1$arousal_c,
# fit = "smooth",
# surface = FALSE,
point.col = "blue",
# point
# ellipsoid = db_full6new_hr_fix_stim_nt1$mediansplit_sample_valence2)
ellipsoid = TRUE)
db_full6new_hr_fix_stim_nt1%>%
group_by(stimIAPS, mediansplit_ground_valence, mediansplit_ground_arousal)%>%
ggplot(aes(mediansplit_ground_valence, ValenceMean))+
geom_point()
db_full6new_hr_fix_stim_nt1%>%
subset(Condition == "IAPS")%>%
group_by(stimIAPS, mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_valence, arousal))+
stat_summary(geom = 'pointrange')+
ggpubr::stat_compare_means()+
geom_text(aes(label = stimIAPS))
check corelation between arousal and valence on and individual basis
db_full6new_hr_fix_stim_nt1$arousal_c
subset(db_full6new_hr_fix_stim_nt1, mediansplit_ground_valence == "More positive" & Bio_Mean_HR_dif_outl == "not outlier") %>%
group_by(ssid)%>%
mutate(cor_vale_ar = cor(arousal, valence, use = "complete"))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(cor_vale_ar))+
geom_histogram()+
geom_vline(xintercept = -.7)
subset(db_full6new_hr_fix_stim_nt1)%>%
# group_by(mediansplit_ground_valence, stimIAPS)%>%
# summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes( valence, arousal))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# geom_smooth(aes(group = ssid), se = F, method = 'lm')+
# facet_grid(~mediansplit_ground_valence)+
ggpubr::stat_cor()
subset(db_full6new_hr_fix_stim_nt1)%>%
subset(ssid == 331)%>%
# group_by(mediansplit_ground_valence, stimIAPS)%>%
# summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes( as.numeric(tNo), arousal))+
geom_point()+
stat_summary(geom = "line")+
geom_point(aes(y = valence), color = "green")+
stat_summary(aes(y = valence),geom = "line", linetype = "dashed", color = "green")
# geom_smooth(method = 'lm', se = F)+
# geom_smooth(aes(group = ssid), se = F, method = 'lm')+
# facet_grid(~mediansplit_ground_valence)+
# ggpubr::stat_cor()
try and regress valence our oarousal_val
db_full6new_hr_fix_stim_nt2
db_full6new_hr_fix_stim_nt3<- subset(db_full6new_hr_fix_stim_nt2, !is.na(valence))
hr_dif_models$arosal_from_val <- lmer(arousal_c~ valence_c + + (1 | ssid) + (1|stimIAPS), # (1|mediansplit_sample_arousal2), REML = FALSE, data = subset(db_full6new_hr_fix_stim_nt3))
hr_dif_models$val_from_arousal <- lmer(valence_c~arousal_c+ + (1 | ssid) + (1|stimIAPS), # (1|mediansplit_sample_arousal2), REML = FALSE, data = subset(db_full6new_hr_fix_stim_nt3))
hr_dif_models\(arosal_from_val plot(hr_dif_models\)arosal_from_val)
?residuals ?resid ?residuals.merMod db_full6new_hr_fix_stim_nt3\(arous_val_resid <- residuals(hr_dif_models\)arosal_from_val)
db_full6new_hr_fix_stim_nt3\(val_from_arous_resid<- residuals(hr_dif_models\)val_from_arousal)
residuals.merMod(hr_dif_models$arosal_from_val)
ar_frm_val<- lm(arousal_c ~ valence_c, data = db_full6new_hr_fix_stim_nt3)
val_frm_val<- lm( valence_c~arousal_c, data = db_full6new_hr_fix_stim_nt3)
db_full6new_hr_fix_stim_nt3%>%ggplot(aes(val_from_arous_resid, arous_val_resid))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ ggpubr::stat_cor()
resid(ar_frm_val)
resid(val_frm_val)
# 1 2 3 4 5 6 7 8
# 0.149962843 0.505815507
#
# -0.637512958 0.044580602
Is the residual of A~ B the same as B~A
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuXG5ocl9kaWZfbW9kZWxzJHZhbF9mcm9tX2Fyb3VzYWwgPC0gbG1lcih2YWxlbmNlX2N+YXJvdXNhbF9jK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKDEgfCBzc2lkKSArICgxfHN0aW1JQVBTKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICgxfG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiksXG4gICAgIFJFTUwgPSBGQUxTRSxcbiAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDMpKVxuXG5cbmhyX2RpZl9tb2RlbHMkYmlvaHJfZGlmX2Fyb3VzX3JlcyA8LSBsbWVyKEJpb19NZWFuX0hSX2RpZn4gIHZhbF9mcm9tX2Fyb3VzX3Jlc2lkICphcm91c192YWxfcmVzaWQrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoMSB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDF8bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSxcbiAgICAgUkVNTCA9IEZBTFNFLFxuICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MywgQmlvX01lYW5fSFJfZGlmX291dGwgPT0gXCJub3Qgb3V0bGllclwiKSlcblxuXG5zdW1tYXJ5KGhyX2RpZl9tb2RlbHMkYmlvaHJfZGlmX2Fyb3VzX3JlcylcblxuIyBhbmFseXNlcyBvZiByZXNpZHVhbHMgYWxzbyBzdWdnZXRzIHRoYXQgZWZmZWN0cyBvbiBiaW9faHIgYXJlIHJlbGF0ZWQgdG8gY29tbW9uIGFyb3VzYWwgYW5kIHZhbGVuY2UgcmVsYXRpb25cblxuYGBgIn0= -->
```r
hr_dif_models$val_from_arousal <- lmer(valence_c~arousal_c+
+ (1 | ssid) + (1|stimIAPS),
# (1|mediansplit_sample_arousal2),
REML = FALSE,
data = subset(db_full6new_hr_fix_stim_nt3))
hr_dif_models$biohr_dif_arous_res <- lmer(Bio_Mean_HR_dif~ val_from_arous_resid *arous_val_resid+
+ (1 | ssid) + (1|stimIAPS),
# (1|mediansplit_sample_arousal2),
REML = FALSE,
data = subset(db_full6new_hr_fix_stim_nt3, Bio_Mean_HR_dif_outl == "not outlier"))
summary(hr_dif_models$biohr_dif_arous_res)
# analyses of residuals also suggets that effects on bio_hr are related to common arousal and valence relation
interactions::interact_plot(hr_dif_models$arousal_val, pred= arousal_c, modx = valence_c)
alexithjymia
db_full6new_hr_fix_stim_nt1\(Bio_Mean_HR_dif_z<- scale(db_full6new_hr_fix_stim_nt1\)Bio_Mean_HR_dif, center = TRUE, scale = TRUE)[,1] hr_dif_models$arousal_val_cat <- lmer(Bio_Mean_HR_dif_z ~TASc*arousal_c+ + (1 | ssid) + (1|stimIAPS), # (1|mediansplit_sample_arousal2), REML = FALSE, data = db_full6new_hr_fix_stim_nt1)
interactions::interact_plot(hr_dif_models$arousal_val_cat, pred= arousal_c, modx = TASc)
summary(hr_dif_models$arousal_val_cat)
plot(hr_dif_models\(arousal_val) plot(hr_dif_models\)arousal_val_cat)
summary(hr_dif_models$arousal_val_cat)
hr_dif_models$arousal_val_cat <- lmer(Bio_Mean_HR_dif~ mediansplit_sample_arousal2* mediansplit_sample_valence2+
+ (1+mediansplit_sample_valence2 | ssid) + (1|stimIAPS),
# (1|mediansplit_sample_arousal2),
REML = FALSE,
data = db_full6new_hr_fix_stim_nt1)
summary(hr_dif_models$arousal_val_cat)
interactions::cat_plot(hr_dif_models$arousal_val_cat, pred = mediansplit_sample_arousal2, modx = mediansplit_sample_valence2)
correlation
db_full6new_hr_fix_stim_nt1%>%
subset(!is.na(mediansplit_ground_valence))%>%
subset(Bio_Mean_HR_dif_outl!= "outlier")%>%
group_by(ssid,mediansplit_ground_valence, mediansplit_ground_arousal)%>%
mutate(cor_hr_arous = cor(Bio_Mean_HR_dif, arousal, use = "complete"))%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(mediansplit_ground_valence, cor_hr_arous))+
# geom_jitter(alpha = .2, width = .2)+
geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
stat_summary(geom = 'pointrange')+
# geom_smooth(aes(group = ssid), color = 'gray', method = 'lm', se = F)+
ggpubr::stat_compare_means()+
facet_grid(~mediansplit_ground_arousal)
# xlim(-5,3)
db_full6new_hr_fix_stim_nt1 %>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(Age, TASc))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
hr_dif_models<- list()
hr_dif_models$arousal_val <- lmer(Bio_Mean_HR_dif~ (arousal_c*valence_c )* TASc +(1+arousal_c | ssid) + (1|stimIAPS),
REML = FALSE,
data = db_full6new_hr_fix_stim_nt1)
summary(hr_dif_models$arousal_val)
interactions::interact_plot(hr_dif_models$arousal_val, pred = arousal_c, modx = TASc)
hr_dif_models$arousal_val <- lmer(Bio_Mean_HR~ arousal_c* valence_c +(1+arousal_c| ssid),
# + (1|stimIAPS),
REML = FALSE,
data = db_full6new_hr_fix_stim_nt1)
summary(hr_dif_models$arousal_val)
# plot(hr_dif_models$arousal_val)
interactions::interact_plot(hr_dif_models$arousal_val, pred = valence_c, modx = arousal_c)
import HRV resting
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuXG5SZXN0X0hSViA8LSByZWFkX2V4Y2VsKFwiUmVzdCBIUlYueGxzeFwiKVxuVmlldyhSZXN0X0hSVikgIFxuXG5SZXN0X0hSViU+JVxuICBnZ3Bsb3QoYWVzKFJNU1NEKSkrXG4gIGdlb21faGlzdG9ncmFtKClcblxuUmVzdF9IUlYlPiVcbiAgZ2dwbG90KGFlcyhSTVNTRCkpK1xuICBnZW9tX2hpc3RvZ3JhbSgpXG5cblJlc3RfSFJWJT4lXG4gIGdncGxvdChhZXMoTUVBTkhSKSkrXG4gIGdlb21faGlzdG9ncmFtKClcblxuQklPX0hSVmFuYWx5c3lzJHNzaWQ8LSBhcy5jaGFyYWN0ZXIoQklPX0hSVmFuYWx5c3lzJHNzaWQpXG5cbmxlZnRfam9pbihCSU9fSFJWYW5hbHlzeXMsIFJlc3RfSFJWLCBieSA9IFwic3NpZFwiKSU+JVxuICBnZ3Bsb3QoYWVzKFJNU1NELCBSTU1TU0QpKStcbiAgZ2VvbV9wb2ludCgpK1xuICBnZ3B1YnI6OnN0YXRfY29yKClcblxuXG4jIGxpYnJhcnkocmVhZHhsKVxuXG5cblJlc3RfcHJhY3RpY2VfSFJWIDwtIHJlYWRfZXhjZWwoXCJSZXN0ICsgcHJhY3RpY2UgSFJWLnhsc3hcIilcblZpZXcoUmVzdF9wcmFjdGljZV9IUlYpXG5SZXN0X3ByYWN0aWNlX0hSViRzc2lkPC0gYXMuY2hhcmFjdGVyKFJlc3RfcHJhY3RpY2VfSFJWJHNzaWQpXG5cbmxlZnRfam9pbihSZXN0X3ByYWN0aWNlX0hSViwgQklPX0hSVmFuYWx5c3lzLCBieSA9IFwic3NpZFwiKSU+JVxuICBnZ3Bsb3QoYWVzKFJNU1NELCBSTU1TU0QpKStcbiAgZ2VvbV9wb2ludCgpK1xuICBnZ3B1YnI6OnN0YXRfY29yKClcblxuXG5sZWZ0X2pvaW4oUmVzdF9wcmFjdGljZV9IUlYsIFJlc3RfSFJWLCBieSA9IFwic3NpZFwiKSU+JVxuICBnZ3Bsb3QoYWVzKFJNU1NELngsIFJNU1NELnkpKStcbiAgZ2VvbV9wb2ludCgpK1xuICBnZ3B1YnI6OnN0YXRfY29yKClcblxuXG5SZXN0X3ByYWN0aWNlX0hSViU+JVxuICBnZ3Bsb3QoYWVzKE1FQU5IUikpK1xuICBnZW9tX2hpc3RvZ3JhbSgpXG4gIFxuIyBpbXBvcnQgaHJ2IHRhc2tcbmxpYnJhcnkocmVhZHhsKVxuaHJ2UmVzdWx0c1Rhc2sgPC0gcmVhZF9leGNlbChcIlN1bW1hcnlfaHJ2UmVzdWx0c1Rhc2sueGxzXCIpXG5WaWV3KGhydlJlc3VsdHNUYXNrKVxuXG5gYGAifQ== -->
```r
Rest_HRV <- read_excel("Rest HRV.xlsx")
View(Rest_HRV)
Rest_HRV%>%
ggplot(aes(RMSSD))+
geom_histogram()
Rest_HRV%>%
ggplot(aes(RMSSD))+
geom_histogram()
Rest_HRV%>%
ggplot(aes(MEANHR))+
geom_histogram()
BIO_HRVanalysys$ssid<- as.character(BIO_HRVanalysys$ssid)
left_join(BIO_HRVanalysys, Rest_HRV, by = "ssid")%>%
ggplot(aes(RMSSD, RMMSSD))+
geom_point()+
ggpubr::stat_cor()
# library(readxl)
Rest_practice_HRV <- read_excel("Rest + practice HRV.xlsx")
View(Rest_practice_HRV)
Rest_practice_HRV$ssid<- as.character(Rest_practice_HRV$ssid)
left_join(Rest_practice_HRV, BIO_HRVanalysys, by = "ssid")%>%
ggplot(aes(RMSSD, RMMSSD))+
geom_point()+
ggpubr::stat_cor()
left_join(Rest_practice_HRV, Rest_HRV, by = "ssid")%>%
ggplot(aes(RMSSD.x, RMSSD.y))+
geom_point()+
ggpubr::stat_cor()
Rest_practice_HRV%>%
ggplot(aes(MEANHR))+
geom_histogram()
# import hrv task
library(readxl)
hrvResultsTask <- read_excel("Summary_hrvResultsTask.xls")
View(hrvResultsTask)
combine with data
Rest_HRV
Rest_HRV$subject<- NULL
nrow(db_full6new_hr_fix_stim_nt1)
# 2160
db_full6new_hr_fix_stim_nt2<- left_join(db_full6new_hr_fix_stim_nt1, Rest_HRV)
# hrv rest vs hrtaskCallbackManager(
left_join(Rest_HRV, hrvResultsTask, by = "ssid") %>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(RMSSD.x, RMSSD.y))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
xlim(0,100)+
ylim(0,100)
Rest_HRV$hrvcondition<- "rest"
hrvResultsTask$hrvcondition<- "task"
left_join(Rest_HRV, hrvResultsTask, by = "ssid") %>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(RMSSD.x, RMSSD.y))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()+
xlim(0,100)+
ylim(0,100)
colnames(hrvResultsTask)
bind_rows(Rest_HRV, hrvResultsTask)%>%
subset(RMSSD<100)%>%
ggplot(aes(hrvcondition, hfpower))+
geom_jitter(width = .1, alpha = .1)+
stat_summary(geom = 'pointrange')+
stat_summary(aes(group = ssid), geom = 'line', alpha = .1)
left_join(db_full6new_hr_fix_stim_nt1, hrvResultsTask) %>%
group_by(ssid)%>%
mutate(cor = cor(arousal, pup_basCor, use = "complete"))%>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(NN50,cor ))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
xlim(0,500)+
ggpubr::stat_cor()
left_join(db_full6new_hr_fix_stim_nt1, hrvResultsTask) %>%
group_by(ssid)%>%
mutate(cor = cor(arousal, pup_basCor, use = "complete"))%>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(TASc, NN50))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# ylim(0,200)+
ggpubr::stat_cor()
hrvResultsTask%>%
ggplot(aes(RMSSD))+
geom_histogram()
left_join(db_full6new_hr_fix_stim_nt1, hrvResultsTask) %>%
subset(!is.na(mediansplit_ground_valence))%>%
# group_by(ssid)%>%
# mutate(cor = cor(arousal, pup_basCor, use = "complete"))%>%
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(RMSSD,pup_basCor,color = mediansplit_ground_valence ))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# xlim(0,100)+
ggpubr::stat_cor()
left_join(db_full6new_hr_fix_stim_nt1, hrvResultsTask) %>%
subset(!is.na(mediansplit_ground_valence))%>%
# group_by(ssid)%>%
# mutate(cor = cor(arousal, pup_basCor, use = "complete"))%>%
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(RMSSD,BIO_CDA.PhasicMax_z,color = mediansplit_ground_valence ))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
xlim(0,100)+
ggpubr::stat_cor()
left_join(db_full6new_hr_fix_stim_nt1, hrvResultsTask) %>%
subset(!is.na(mediansplit_ground_valence))%>%
subset(Bio_Mean_HR_dif_outl == "not outlier")%>%
# group_by(ssid)%>%
# mutate(cor = cor(arousal, pup_basCor, use = "complete"))%>%
group_by(ssid,mediansplit_ground_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(`LF/HF`,BIO_CDA.PhasicMax_z,color = mediansplit_ground_valence ))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
# xlim(0,5000)+
ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt2 %>% group_by(ssid)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(Bio_Mean_HR_dif, lfpower))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt2 %>% group_by(ssid)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(MEANHR, RMSSD))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ ggpubr::stat_cor()
db_full6new_hr_fix_stim_nt2 %>% group_by(ssid)%>% summarise_if(is.numeric, mean, na.rm = TRUE)%>% ggplot(aes(MEANHR, Bio_Mean_HR))+ geom_point()+ geom_smooth(method = ‘lm’, se = F)+ ggpubr::stat_cor()
<!-- rnb-text-end -->
<!-- rnb-chunk-begin -->
<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuIyB3b3JrIG9uIHRoaXNcbmRiX2Z1bGw2bmV3XzMwNF91cCRcbmNvbG5hbWVzKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QpXG5jb2xuYW1lcyhkYl9mdWxsNm5ld18zMDRfdXApXG4jIGRiX2Z1bGw2bmV3XG51bmlxdWUoZGJfZnVsbDZuZXdfMzA0X3VwJHNjcmVlbmNvbnRlbnQpXG5cblZpZXcoZGJfZnVsbDZuZXcpXG5cbiMgc3RvcmUgaGVhcnQgcmF0ZSBiYXNlbGluZSB0byBjb21wdXRlIGRpZmZlcmVuY2VcbmRiX2Z1bGw2bmV3JEJpb19NZWFuX0hSX2ZpeCA9IGlmX2Vsc2UoZGJfZnVsbDZuZXckc2NyZWVuY29udGVudCA9PSBcImZpeGF0aW9uXCIsIGRiX2Z1bGw2bmV3JEJpb19NZWFuX0hSLCBOVUxMKVxuXG4jIGNvbXB1dGUgaGVhcnQgcmF0ZSBkaWZmZXJlbmNlIHRvIGZpeGF0aW9uIHNjcmVlblxuXG5kYl9mdWxsNm5ld18zMDRfdXAkQmlvX01lYW5fSFJcblZpZXcoZGJfZnVsbDZuZXdfMzA0X3VwKVxuXG5kYl9mdWxsNm5ld18zMDRfdXA8LSBkYl9mdWxsNm5ld18zMDRfdXAlPiVcbiAgZ3JvdXBfYnkoc3NpZCklPiVcbiAgbXV0YXRlKEJJT19DREEuUGhhc2ljTWF4X3ogPSBzY2FsZShCSU9fQ0RBLlBoYXNpY01heClbLDFdKVxuXG5cblxucHVwdWxyZXNpZHRlc3Q8LSBsbWVyKHB1cF9iYXNDb3IgfiBCUklHSFRORVNTYyArKDErQlJJR0hUTkVTU2N8c3NpZCksIFJFTUwgPSBGQUxTRSxcbiAgICAgZGF0YSA9IHRlc3RyZXNpZGRmKVxuXG5zdW1tYXJ5KHB1cHVscmVzaWR0ZXN0KVxuXG5cbnBsb3QocHVwdWxyZXNpZHRlc3QpXG5cbnJlc2lkKHB1cHVscmVzaWR0ZXN0KVxudHN0cmVzaWQgPC0gcmVzaWQocHVwdWxyZXNpZHRlc3QpXG5cblxudGVzdHJlc2lkZGYkcHVvcGlsX3Jlc2lkIDwtIHRzdHJlc2lkXG5cbnRlc3RyZXNpZGRmPC0gc3Vic2V0KGRiX2Z1bGw2bmV3XzMwNF91cCwgIWlzLm5hKHB1cF9iYXNDb3IpKVxuXG5cbnN1bW1hcnkobG1lcihhcm91c2FsIH4gcHVwaWxfcmVzaWQgKyAoMXxzc2lkKSwgUkVNTCA9IEZBTFNFLFxuICAgICBkYXRhID0gdGVzdHJlc2lkZGYpKVxuXG5cblxuc3VtbWFyeShsbWVyKGFyb3VzYWwgfiBwdW9waWxfcmVzaWQgKyBCaW9fTWVhbl9IUitCSU9fQ0RBLlBoYXNpY01heCArICgxfHNzaWQpLFxuICAgICAgICAgICAgICAjICgwK3B1b3BpbF9yZXNpZCArIEJpb19NZWFuX0hSK0JJT19DREEuUGhhc2ljTWF4fHNzaWQpLCBcbiAgICAgICAgICAgICBSRU1MID0gRkFMU0UsXG4gICAgIGRhdGEgPSBzdWJzZXQodGVzdHJlc2lkZGYsIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHNzaWQpKTw1MDApKSkgXG5cblxuc3Vic2V0KHRlc3RyZXNpZGRmLCBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcihzc2lkKSk8NTAwKSU+JVxuICBncm91cF9ieShzc2lkKSU+JVxuICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JVxuICBnZ3Bsb3QoYWVzKGFyb3VzYWwsIEJJT19DREEuUGhhc2ljTWF4KSkrXG4gIGdlb21fcG9pbnQoKStcbiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKStcbiAgZ2dwdWJyOjpzdGF0X2NvcigpXG5cbnN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCklPiVcbiAgbXV0YXRlKG1lZGlhbl9ncm91bmRfYXJvdXNhbCA9IGlmX2Vsc2UoQXJvdXNhbE1lYW4+IG1lZGlhbihBcm91c2FsTWVhbiwgbmEucm0gPSBUUlVFKSwgXCJIaWdoXCIsIFwiTG93XCIpKSU+JVxuICBtdXRhdGUobWVkaWFuX2dyb3VuZF92YWxlbmNlID0gaWZfZWxzZShWYWxlbmNlTWVhbj4gbWVkaWFuKFZhbGVuY2VNZWFuLCBuYS5ybSA9IFRSVUUpLCBcIk1vcmUgcG9zaXRpdmVcIiwgXCJNb3JlIG5lZ2F0aXZlXCIpKSU+JVxuICBncm91cF9ieShzc2lkKSU+JVxuICB1bmdyb3VwKCklPiVcbiAgbXV0YXRlKG1lZGlhbl9zZWxmX2Fyb3VzYWwgPSBpZl9lbHNlKGFyb3VzYWw+IG1lZGlhbihhcm91c2FsKSwgXCJIaWdoXCIsIFwiTG93XCIpKSU+JVxuICBtdXRhdGUobWVkaWFuX3NlbGZfdmFsZW5jZSA9IGlmX2Vsc2UodmFsZW5jZT4gbWVkaWFuKHZhbGVuY2UpLCBcIlBvc2l0aXZlXCIsIFwiTmVnYXRpdmVcIikpJT4lXG5ncm91cF9ieShzc2lkLG1lZGlhbl9zZWxmX2Fyb3VzYWwsbWVkaWFuX3NlbGZfdmFsZW5jZSklPiVcbiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiVcbiAgZ2dwbG90KGFlcyhtZWRpYW5fc2VsZl9hcm91c2FsLCBwdW9waWxfcmVzaWQsKSkrXG4gIGdlb21faml0dGVyKHdpZHRoID0gLjIsIGFscGhhID0gLjIpK1xuICAgZ2VvbV9iYXIoc3RhdD1cInN1bW1hcnlcIiwgZnVuLnkgPSBcIm1lYW5cIiwgYWxwaGEgPSAuMikrXG4gIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKStcbiAgICBmYWNldF9ncmlkKH5tZWRpYW5fc2VsZl92YWxlbmNlKVxuICBnZ3B1YnI6OnN0YXRfY29yKClcbiAgXG4gIFxuICBcbiAgXG4gIHN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCklPiVcbiAgbXV0YXRlKG1lZGlhbl9ncm91bmRfYXJvdXNhbCA9IGlmX2Vsc2UoQXJvdXNhbE1lYW4+IG1lZGlhbihBcm91c2FsTWVhbiwgbmEucm0gPSBUUlVFKSwgXCJIaWdoXCIsIFwiTG93XCIpKSU+JVxuICBtdXRhdGUobWVkaWFuX2dyb3VuZF92YWxlbmNlID0gaWZfZWxzZShWYWxlbmNlTWVhbj4gbWVkaWFuKFZhbGVuY2VNZWFuLCBuYS5ybSA9IFRSVUUpLCBcIk1vcmUgcG9zaXRpdmVcIiwgXCJNb3JlIG5lZ2F0aXZlXCIpKSU+JVxuICBncm91cF9ieShzc2lkKSU+JVxuICBtdXRhdGUobWVkaWFuX3NlbGZfYXJvdXNhbCA9IGlmX2Vsc2UoYXJvdXNhbD4gbWVkaWFuKGFyb3VzYWwpLCBcIkhpZ2hcIiwgXCJMb3dcIikpJT4lXG4gIG11dGF0ZShtZWRpYW5fc2VsZl92YWxlbmNlID0gaWZfZWxzZSh2YWxlbmNlPiBtZWRpYW4odmFsZW5jZSksIFwiUG9zaXRpdmVcIiwgXCJOZWdhdGl2ZVwiKSklPiVcbmdyb3VwX2J5KHNzaWQsbWVkaWFuX3NlbGZfYXJvdXNhbCklPiVcbiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiVcbiAgICBzdWJzZXQoIWlzLm5hKG1lZGlhbl9zZWxmX2Fyb3VzYWwpKSU+JVxuICBnZ3Bsb3QoYWVzKG1lZGlhbl9zZWxmX2Fyb3VzYWwsIEJJT19DREEuUGhhc2ljTWF4X3opKStcbiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMiwgYWxwaGEgPSAuMikrXG4gICBnZW9tX2JhcihzdGF0PVwic3VtbWFyeVwiLCBmdW4ueSA9IFwibWVhblwiLCBhbHBoYSA9IC4yKStcbiAgICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHNzaWQpLG1ldGhvZCA9ICdsbScsIHNlID0gRikrXG4gICAgIyBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3NpZCkpXG4gIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKVxuICAgIGZhY2V0X2dyaWQofm1lZGlhbl9zZWxmX3ZhbGVuY2UpXG4gIGdncHVicjo6c3RhdF9jb3IoKVxuICBcbiAgXG4gIHN1bW1hcnkobG1lcihhcm91c2FsIH4gbG9nKEJJT19DREEuUGhhc2ljTWF4Ky4xKSArICgxfHNzaWQpICsgKDErbG9nKEJJT19DREEuUGhhc2ljTWF4Ky4xKXxzdGltSUFQUyksXG4gICAgICAgICAgICAgICMgKDArcHVvcGlsX3Jlc2lkICsgQmlvX01lYW5fSFIrQklPX0NEQS5QaGFzaWNNYXh8c3NpZCksIFxuICAgICAgICAgICAgIFJFTUwgPSBGQUxTRSxcbiAgICAgZGF0YSA9IHN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCAmQklPX0NEQS5BbXBTdW0+IC4xKSkpXG5cblxuXG5cblxuXG5gYGAifQ== -->
```r
# work on this
db_full6new_304_up$
colnames(db_full4new_stim_screen_pupil_nopract)
colnames(db_full6new_304_up)
# db_full6new
unique(db_full6new_304_up$screencontent)
View(db_full6new)
# store heart rate baseline to compute difference
db_full6new$Bio_Mean_HR_fix = if_else(db_full6new$screencontent == "fixation", db_full6new$Bio_Mean_HR, NULL)
# compute heart rate difference to fixation screen
db_full6new_304_up$Bio_Mean_HR
View(db_full6new_304_up)
db_full6new_304_up<- db_full6new_304_up%>%
group_by(ssid)%>%
mutate(BIO_CDA.PhasicMax_z = scale(BIO_CDA.PhasicMax)[,1])
pupulresidtest<- lmer(pup_basCor ~ BRIGHTNESSc +(1+BRIGHTNESSc|ssid), REML = FALSE,
data = testresiddf)
summary(pupulresidtest)
plot(pupulresidtest)
resid(pupulresidtest)
tstresid <- resid(pupulresidtest)
testresiddf$puopil_resid <- tstresid
testresiddf<- subset(db_full6new_304_up, !is.na(pup_basCor))
summary(lmer(arousal ~ pupil_resid + (1|ssid), REML = FALSE,
data = testresiddf))
summary(lmer(arousal ~ puopil_resid + Bio_Mean_HR+BIO_CDA.PhasicMax + (1|ssid),
# (0+puopil_resid + Bio_Mean_HR+BIO_CDA.PhasicMax|ssid),
REML = FALSE,
data = subset(testresiddf, as.numeric(as.character(ssid))<500)))
subset(testresiddf, as.numeric(as.character(ssid))<500)%>%
group_by(ssid)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(arousal, BIO_CDA.PhasicMax))+
geom_point()+
geom_smooth(method = 'lm', se = F)+
ggpubr::stat_cor()
subset(testresiddf, as.numeric(as.character(ssid))<500)%>%
mutate(median_ground_arousal = if_else(ArousalMean> median(ArousalMean, na.rm = TRUE), "High", "Low"))%>%
mutate(median_ground_valence = if_else(ValenceMean> median(ValenceMean, na.rm = TRUE), "More positive", "More negative"))%>%
group_by(ssid)%>%
ungroup()%>%
mutate(median_self_arousal = if_else(arousal> median(arousal), "High", "Low"))%>%
mutate(median_self_valence = if_else(valence> median(valence), "Positive", "Negative"))%>%
group_by(ssid,median_self_arousal,median_self_valence)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
ggplot(aes(median_self_arousal, puopil_resid,))+
geom_jitter(width = .2, alpha = .2)+
geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
stat_summary(geom = 'pointrange')+
facet_grid(~median_self_valence)
ggpubr::stat_cor()
subset(testresiddf, as.numeric(as.character(ssid))<500)%>%
mutate(median_ground_arousal = if_else(ArousalMean> median(ArousalMean, na.rm = TRUE), "High", "Low"))%>%
mutate(median_ground_valence = if_else(ValenceMean> median(ValenceMean, na.rm = TRUE), "More positive", "More negative"))%>%
group_by(ssid)%>%
mutate(median_self_arousal = if_else(arousal> median(arousal), "High", "Low"))%>%
mutate(median_self_valence = if_else(valence> median(valence), "Positive", "Negative"))%>%
group_by(ssid,median_self_arousal)%>%
summarise_if(is.numeric, mean, na.rm = TRUE)%>%
subset(!is.na(median_self_arousal))%>%
ggplot(aes(median_self_arousal, BIO_CDA.PhasicMax_z))+
geom_jitter(width = .2, alpha = .2)+
geom_bar(stat="summary", fun.y = "mean", alpha = .2)+
# geom_smooth(aes(group = ssid),method = 'lm', se = F)+
# geom_text(aes(label = ssid))
stat_summary(geom = 'pointrange')
facet_grid(~median_self_valence)
ggpubr::stat_cor()
summary(lmer(arousal ~ log(BIO_CDA.PhasicMax+.1) + (1|ssid) + (1+log(BIO_CDA.PhasicMax+.1)|stimIAPS),
# (0+puopil_resid + Bio_Mean_HR+BIO_CDA.PhasicMax|ssid),
REML = FALSE,
data = subset(testresiddf, as.numeric(as.character(ssid))<500 &BIO_CDA.AmpSum> .1)))
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCgpEb3duc2FtcGxlIGRhdGEgdG8gc2F2ZSBzcGFjZQoKcHVwaWx0aW1lY291cnNlLmRhdGEgaXMgZG93c25hbXBsZWQgYnV0IGRvZXNuJ3QgaGF2ZSBhbGwgcGFydGljaXBhbnRzIDwgNDAwCgpidXQgdGhlIHNjcmlwdCBwdXBpbHRpbWVjb3Vyc2VleHAyLlJtZCBoYXMgd2hhdCB3ZSBuZWVkIHRvIGRvIHRoZSBzYW1lIGRvd3NuYW1wbGluZwoKR29hbAotIHRha2UgcHVwaWwgdGltZWNvdXJzZSwgZG93c25hbXBsZSBhbmQgdGhlbiBtcmdlIGl0IGl0IGJlaGF2aW91cmFsIGRhdGEgc28gdGhhdCB3ZSBjYW4gZG8gdGhlIGFkZGl0aW9uYWwgYXJvdXNhbCBwdXBpbCBhbmFseXNlcyB0aGF0IGNoZWNrIGZvciB0aW1lY291cnNlIHRoaW5ncy4KCgoKY2hlY2sgZ2F6ZVIgb3IgZG93bnNhbXBsaW5nCgoKdG8gZG8sIGRvIHRoZSBzYW1lIGFyb3VzYWwgY29ycmVsYXRpb24gd2l0aCB2YWxlbmNlCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodGlkeXZlcnNlKQppbnN0YWxsLnBhY2thZ2VzKCJnYXplciIpCmxpYnJhcnkoZ2F6ZXIpCgo/Z2F6ZXI6OmRvd25zYW1wbGVfZ2F6ZQo/Z2F6ZXI6OmRvd25zYW1wbGVfcHVwaWwKCgp1bmlxdWUoWF90bXBfZGY0X2Z1bGwkQ29uZGl0aW9uKQojIGdhemVyOjpkb3duc2FtcGxlX2dhemUlCgp0bXAuZGY0X2Z1bGxfc3RpbTwtIFhfdG1wX2RmNF9mdWxsICU+JQogIHN1YnNldChzY3JlZW5jb250ZW50ID09ICJzdGltIikKCgojIGNyZWF0ZSBiaW5zCiMgaW5zdGFsbC5wYWNrYWdlcygiT25lUiIpCmluc3RhbGwucGFja2FnZXMoIk9uZVIiKQpsaWJyYXJ5KE9uZVIpCgo/YmluCgoKdG1wLmRmNF9mdWxsX3N0aW0kdGltZWJpbjwtIE9uZVI6OmJpbih0bXAuZGY0X2Z1bGxfc3RpbSR0aW1lcmV6ZXJvMywgbmJpbiA9IDYwKQoKCgojIGRvd3NhbXBsZSBieSBhdmVyYWdpbmc/CmNvbG5hbWVzKHRtcC5kZjRfZnVsbF9zdGltKQp0bXAuZGY0X2Z1bGxfc3RpbV9kb3ducyA8LSB0bXAuZGY0X2Z1bGxfc3RpbSAlPiUKICBncm91cF9ieShzc2lkLCB0Tm8sIHRpbWViaW4sIHRyaWFsLHRyaWFsVW5xKSU+JQogIHN1bW1hcmlzZV9hdChjKCd0aW1lcmV6ZXJvMycsJ3B1cF9iYXNDb3InLCAnZ2F6ZV94X2Nvcl9waXgnLCAnZ2F6ZV95X2Nvcl9waXgnKSwgCiAgICAgICAgICAgICAgIG1lYW4sIG5hLnJtID0gVFJVRSkKCgo/c2F2ZVJEUwpzYXZlUkRTKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zLCAidG1wLmRmNF9mdWxsX3N0aW1fZG93bnMucmRzIikKCiMgY3JlYXRlIGtsYXJnZXIgYmlucwp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoCgpyYW5nZSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3ducyR0aW1lcmV6ZXJvMykKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkdGltZWJpbjI8LSBPbmVSOjpiaW4odG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCR0aW1lcmV6ZXJvMywgbmJpbiA9IDMwKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIgPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBncm91cF9ieShzc2lkLCB0Tm8sIHRpbWViaW4yLCB0cmlhbCx0cmlhbFVucSklPiUKICBzdW1tYXJpc2VfYXQoYygndGltZXJlemVybzMnLCdwdXBfYmFzQ29yJywgJ2dhemVfeF9jb3JfcGl4JywgJ2dhemVfeV9jb3JfcGl4JyksIAogICAgICAgICAgICAgICBtZWFuLCBuYS5ybSA9IFRSVUUpCgpucm93KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyKQo4NzUyOQpgYGAKCgpwdXBpbCBhcm91c2FsCgpgYGB7cn0KbGlicmFyeShnZ2hhbHZlcykKCiMgcHVwaWwgdHJhY2tzIGFyb3VzYWwKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgZ3JvdW5kX2Fyb3VzYWxfbGFiLCBBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoZ3JvdW5kX2Fyb3VzYWxfbGFiLCBwdXBfYmFzQ29yLCBjb2xvciA9IGdyb3VuZF9hcm91c2FsX2xhYixmaWxsID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSkrCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMiwgYWxwaGEgPSAuMikrCiAjIGdlb21faGFsZl92aW9saW4oY29sb3VyID0gRkFMU0UsIGFscGhhID0gLjMsIHNpemUgPSA1KSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIHdpZHRoID0xKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiQXJvdXNhbCIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkKICAjIGZhY2V0X2dyaWQofkJSSUdIVE5FU1NfbWVkaWFuc3BsaXQpKwogIHlsaW0oLTYsMi4zKQogIAogIAogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfc2VsZl9hcm91c2FsLCBBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbCwgcHVwX2Jhc0NvciwgY29sb3IgPSBtZWRpYW5zcGxpdF9zZWxmX2Fyb3VzYWwsZmlsbCA9IG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbCkpKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIsIGFscGhhID0gLjIpKwogIyBnZW9tX2hhbGZfdmlvbGluKGNvbG91ciA9IEZBTFNFLCBhbHBoYSA9IC4zLCBzaXplID0gNSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCB3aWR0aCA9MSkrCiAgcCRncmFwaHN0eWxlKwogICMgeGxhYigiQXJvdXNhbCIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpCiAgIyBmYWNldF9ncmlkKH5CUklHSFRORVNTX21lZGlhbnNwbGl0KSsKICB5bGltKC02LDIuMykKICAKbWVkaWFuc3BsaXRfc2VsZl9hcm91c2FsX3RoaXNzYW1wbGUKICAKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KHNzaWQ8IDUwMCklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAgIGdyb3VwX2J5KHNzaWQsIG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbF90aGlzc2FtcGxlLCBBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlX3RoaXNzYW1wbGUpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfc2VsZl9hcm91c2FsX3RoaXNzYW1wbGUsIHB1cF9iYXNDb3IsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2VsZl9hcm91c2FsX3RoaXNzYW1wbGUsZmlsbCA9IG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbF90aGlzc2FtcGxlKSkrCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMiwgYWxwaGEgPSAuMikrCiAjIGdlb21faGFsZl92aW9saW4oY29sb3VyID0gRkFMU0UsIGFscGhhID0gLjMsIHNpemUgPSA1KSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIHdpZHRoID0xKSsKICBwJGdyYXBoc3R5bGUrCiAgIyB4bGFiKCJBcm91c2FsIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZV90aGlzc2FtcGxlKQogICMgZmFjZXRfZ3JpZCh+QlJJR0hUTkVTU19tZWRpYW5zcGxpdCkrCiAgeWxpbSgtNiwyLjMpCiAgCiAgCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCU+JQogICAgCiAgICAgZ2dwbG90KGFlcyggdmFsZW5jZSxhcm91c2FsKSkrCiAgICBnZW9tX3BvaW50KCkrCiAgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4ICsgSSh4XjIpLCBzaXplID0gMSkrCiAgICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX2Fyb3VzYWwpCiAgICAjIGdlb21fc21vb3RoKGFlcyh4ID0gYXJvdXNhbF4yLCB5ID0gdmFsZW5jZSkpCiAgIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QlPiUKICAgIAogICAgZ2dwbG90KGFlcyggdmFsZW5jZSxhcm91c2FsKSkrCiAgICBnZW9tX3BvaW50KCkrCiAgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4ICsgSSh4XjIpLCBzaXplID0gMSkrCiAgICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpCiAgIAogICAKICAgdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3Qkc3NpZCkKYGBgCiAgCmBgYHtyfQojIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSBpcyBkdW9saWF0aW5nIHRoZSBzdGltdWxpIGJhc2VkIGlvbiBwZW9wbCB3aG8gY2hvb3NlIG5lZ2F0aXZlIGFuZCBwb3NpdGl2ZQp1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCkKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCA8LSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JT4lCiAgdW5ncm91cCgpJT4lCiAgIyBncm91cF9ieShzdGltSUFQUyklPiUKICBtdXRhdGUobWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyID0gaWZfZWxzZShWYWxlbmNlTWVhblRoaXNTYW1wbGUgPj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW4oVmFsZW5jZU1lYW5UaGlzU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLCAiTW9yZSBwb3NpdGl2ZSIsICJNb3JlIG5lZ2F0aXZlIikpJT4lCiAgbXV0YXRlKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiA9IGlmX2Vsc2UoQXJvdXNhbE1lYW5UaGlzU2FtcGxlID49CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuKEFyb3VzYWxNZWFuVGhpc1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKSwgIkhpZ2giLCAiTG93IikpCiAgCiAgCiAgZ3JvdXBfYnkobWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLCBzdGltSUFQUyxzdGltRGVzY3JpcHRpb24pJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSkKCmBgYAoKICAKICAKYnJpZ2h0bmVzcwoKYGBge3J9CnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXclPiUKICBncm91cF9ieShzdGltSUFQUyklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoVmFsZW5jZU1lYW4sIE1lYW5fZ3JheV96KSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyU+JQogIGdyb3VwX2J5KHN0aW1JQVBTKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhBcm91c2FsTWVhbiwgTWVhbl9ncmF5X3opKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3ICU+JQogIGdyb3VwX2J5KHN0aW1JQVBTLGdyb3VuZF92YWxlbmNlX2xhYiklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoZ3JvdW5kX3ZhbGVuY2VfbGFiLCBNZWFuX2dyYXlfeikpKwogIGdlb21fcG9pbnQoKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIAogIAogIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcgJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMsbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBNZWFuX2dyYXlfeikpKwogICMgZ2VvbV9wb2ludCgpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgCiAgCiAgCiAgICB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3ICU+JQogIGdyb3VwX2J5KHN0aW1JQVBTLGdyb3VuZF92YWxlbmNlX2xhYiklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoTWVhbl9ncmF5X3osIGNvbG9yID0gZ3JvdW5kX3ZhbGVuY2VfbGFiKSkrCiAgICAgICMgZ2VvbV9oaXN0b2dyYW0oKSsKICAgICAgZ2VvbV9kZW5zaXR5KCkKICAjIGdlb21fcG9pbnQoKSsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpLGdlb20gPSAnbGluZScpCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICAKICAKICAKICAKICAjIAogIAp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3ICU+JQogIGdyb3VwX2J5KHN0aW1JQVBTLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgQXJvdXNhbE1lYW4pKSsKICAgICAgIyBnZW9tX2hpc3RvZyBgdnJhbSgpCiAgICAgICMgZ2VvbV9kZW5zaXR5KCkKICAjIGdlb21fcG9pbnQoKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykKICAjIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgIyBnZ3B1YnI6OnN0YXRfY29yKCkKICAgICAgCiAgICAgIAogICAgICBncm91bmRfdmFsZW5jZV9sYWIKYGBgCgogIApQYXJ0aWNpcGFudHMgc2VjdGlvbgoKYGBge3J9CnBhcnRpY2lwYW50c19kZW1vZyA8LSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICAgIyBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoR3JvdXAgPT0gIk5UIiklPiUKICBncm91cF9ieShzc2lkLCBHZW5kZXIpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSkKCnVuaXF1ZShwYXJ0aWNpcGFudHNfZGVtb2cpCgojIGdlbmRlcgp0YWJsZShwYXJ0aWNpcGFudHNfZGVtb2ckR2VuZGVyKQoKCmNvbG5hbWVzKHBhcnRpY2lwYW50c19kZW1vZykKcHN5Y2g6OmRlc2NyaWJlKHBhcnRpY2lwYW50c19kZW1vZ1tjKCJBZ2UiKV0pCgpzdW1tYXJ5KHBhcnRpY2lwYW50c19kZW1vZyRBZ2UpCgpzZChwYXJ0aWNpcGFudHNfZGVtb2ckQWdlLCBuYS5ybSA9IFRSVUUpCgoKCnRhYmxlKGlzLm5hKHBhcnRpY2lwYW50c19kZW1vZyRBZ2UpKQoKCnBhcnRpY2lwYW50c19kZW1vZyAlPiUKICBncm91cF9ieShHZW5kZXIpJT4lCiAgbXV0YXRlKGdlbmRlcnNwZWNpZl9hZ2UgPSBzZChUQVMpKSU+JQogIHVuZ3JvdXAoKSU+JQogIG11dGF0ZShub25nZW5kZXJzcGVjaWZfYWdlID0gc2QoVEFTKSklPiUKICBncm91cF9ieShHZW5kZXIpJT4lCiAgc3VtbWFyaXNlX2F0KGMoImdlbmRlcnNwZWNpZl9hZ2UiLCJub25nZW5kZXJzcGVjaWZfYWdlIiksIG1lYW4sIG5hLnJtID0gVFJVRSkKCgooMTAuNTU3MTQwKzguMDQyNzQzKS8yCgo4LjA0Mjc0MwoKOS4yOTk5NDEKCmBgYAoKCgogIAogIApgYGB7cn0KICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KEdyb3VwID09ICJOVCIpJT4lCiAgIyBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwsIEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgcHVwX2Jhc0NvciwgY29sb3IgPSBtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCxmaWxsID0gbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwpKSsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAyLCBhbHBoYSA9IC4yKSsKICMgZ2VvbV9oYWxmX3Zpb2xpbihjb2xvdXIgPSBGQUxTRSwgYWxwaGEgPSAuMywgc2l6ZSA9IDUpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgYWxwaGEgPSAuMSwgc2l6ZSA9IDEsIGNvbG91ciA9ICJCbGFjayIpICsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJywgd2lkdGggPTEpKwogIHAkZ3JhcGhzdHlsZSsKICAjIHhsYWIoIkFyb3VzYWwiKSsKICAjIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpCiAgIyBmYWNldF9ncmlkKH5CUklHSFRORVNTX21lZGlhbnNwbGl0KSsKICB5bGltKC02LDIuMykKYGBgCgogIAogIApgYGB7cn0KICAKICAgIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwsIEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgTWVhbiwgY29sb3IgPSBtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCxmaWxsID0gbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwpKSsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAyLCBhbHBoYSA9IC4yKSsKICMgZ2VvbV9oYWxmX3Zpb2xpbihjb2xvdXIgPSBGQUxTRSwgYWxwaGEgPSAuMywgc2l6ZSA9IDUpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgYWxwaGEgPSAuMSwgc2l6ZSA9IDEsIGNvbG91ciA9ICJCbGFjayIpICsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJywgd2lkdGggPTEpKwogIHAkZ3JhcGhzdHlsZSsKICAjIHhsYWIoIkFyb3VzYWwiKSsKICAjIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogICMgZmFjZXRfZ3JpZCh+QlJJR0hUTkVTU19tZWRpYW5zcGxpdCkrCiAgeWxpbSg5MCwxMzApCiAgCiAgCmBgYAogIAogIAogIG9rYXkgbGV0J3MgY3JlYXRlIGF2ZXJhZ2VzIGZyaW8gdGhpcyBlbnRpcmUgc2FtcGxlIGFuZCB1c2UgdGhvc2UgdG8gZGV2aWRlIHRoZSBzdGltdWxpCiAgCiAgc2VsZiBhcm9wdXNhbCBtaWdodCBiZSBiaWFzZWQgYnkgcHJvYmxlbWF0aWMgZm9sa3MgYnV0IGF2ZXJhZ2VzIGZvciB0aGUgZW50aXJlIHNhbXBsZSBzaG91bGQgbm90CiAgCmBgYHtyfQoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBncm91cF9ieShzdGltSUFQUyklPiUKICBtdXRhdGUoKQoKCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkX251bTwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgc2VsZl9hcm91c2FsX2xhYiwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKHNlbGZfYXJvdXNhbF9sYWIsIHB1cF9iYXNDb3IsIGNvbG9yID0gc2VsZl9hcm91c2FsX2xhYixmaWxsID0gc2VsZl9hcm91c2FsX2xhYikpKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIsIGFscGhhID0gLjIpKwogIyBnZW9tX2hhbGZfdmlvbGluKGNvbG91ciA9IEZBTFNFLCBhbHBoYSA9IC4zLCBzaXplID0gNSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCB3aWR0aCA9MSkrCiAgcCRncmFwaHN0eWxlKwogICMgeGxhYigiQXJvdXNhbCIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpCiAgCiAgCnNhbXBsZV9pYXBzX2Fyb3VzYWw8LSAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIAogICAgZ3JvdXBfYnkoc3RpbUlBUFMpJT4lCiAgICBzdWJzZXQoc3NpZF9udW08IDUwMCklPiUKICAgIHN1bW1hcmlzZV9hdChjKCdBcm91c2FsTWVhblRoaXNTYW1wbGUnLCdBcm91c2FsTWVhbicpLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICBnZ3Bsb3QoYWVzKEFyb3VzYWxNZWFuVGhpc1NhbXBsZSwgQXJvdXNhbE1lYW4pKSsKICAgIGdlb21fcG9pbnQoKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgICBnZ3B1YnI6OnN0YXRfY29yKCkrCiAgICB0aGVtZV9jbGFzc2ljKCkKICAKICBzYW1wbGVfaWFwc192YWw8LSAgIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgICAKICAgICBncm91cF9ieShzdGltSUFQUyklPiUKICAgIHN1YnNldChzc2lkX251bTwgNTAwKSU+JQogICAgc3VtbWFyaXNlX2F0KGMoJ1ZhbGVuY2VNZWFuVGhpc1NhbXBsZScsJ1ZhbGVuY2VNZWFuJyksIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAgIGdncGxvdChhZXMoVmFsZW5jZU1lYW5UaGlzU2FtcGxlLCBWYWxlbmNlTWVhbikpKwogICAgZ2VvbV9wb2ludCgpKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICAgIGdncHVicjo6c3RhdF9jb3IoKSsKICAgICAgdGhlbWVfY2xhc3NpYygpCgpsaWJyYXJ5KHBhdGNod29yaykKc2FtcGxlX2lhcHNfYXJvdXNhbCsKc2FtcGxlX2lhcHNfdmFsCmBgYAoKCiAgCgogIApgYGB7cn0gCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkX251bTwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgc2VsZl9hcm91c2FsX2xhYiwgQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhzZWxmX2Fyb3VzYWxfbGFiLCBwdXBfYmFzQ29yLCBjb2xvciA9IHNlbGZfYXJvdXNhbF9sYWIsZmlsbCA9IHNlbGZfYXJvdXNhbF9sYWIpKSsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAyLCBhbHBoYSA9IC4yKSsKICMgZ2VvbV9oYWxmX3Zpb2xpbihjb2xvdXIgPSBGQUxTRSwgYWxwaGEgPSAuMywgc2l6ZSA9IDUpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgYWxwaGEgPSAuMSwgc2l6ZSA9IDEsIGNvbG91ciA9ICJCbGFjayIpICsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJywgd2lkdGggPTEpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJBcm91c2FsIikrCiAgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpCiAgIyBmYWNldF9ncmlkKH5CUklHSFRORVNTX21lZGlhbnNwbGl0KSsKICB5bGltKC02LDIuMykKCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkX251bTwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCwgZ3JvdW5kX2Fyb3VzYWxfbGFiLCBBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoZ3JvdW5kX2Fyb3VzYWxfbGFiLCBwdXBfYmFzQ29yLCBjb2xvciA9IGdyb3VuZF9hcm91c2FsX2xhYixmaWxsID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSkrCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMiwgYWxwaGEgPSAuMikrCiAjIGdlb21faGFsZl92aW9saW4oY29sb3VyID0gRkFMU0UsIGFscGhhID0gLjMsIHNpemUgPSA1KSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIHdpZHRoID0xKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiQXJvdXNhbCIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkKICAjIGZhY2V0X2dyaWQofkJSSUdIVE5FU1NfbWVkaWFuc3BsaXQpKwogIHlsaW0oLTYsMi4zKQoKCmBgYAoKUmVzcG9zbmUgYmlhcwpgYGB7cn0KbGlicmFyeShnZ0V4dHJhKQphcm91c19wdXBfYnlfdmFsPC0gZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIGdyb3VwX2J5KHNzaWQsIHN0aW1JQVBTLCBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGFyb3VzYWxfYywgcHVwX2Jhc0NvcikpKwogICAgICBnZW9tX3BvaW50KGFscGhhID0gLjIpKwogICAgIyBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiQXJvdXNhbCIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKQogICMgZ2dwdWJyOjpzdGF0X2NvcigpCiAgeWxpbSgtMy4zLDEuMykKCiAgYXJvdXNfcHVwX2J5X3ZhbDwtIGFyb3VzX3B1cF9ieV92YWwrZ2dzaWRlOjpnZW9tX3hzaWRlZGVuc2l0eShhZXMoeT1zdGF0KGRlbnNpdHkpLGZpbGwgPSBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpLCBhbHBoYSA9IC40KQogICAgCiAgYXJvdXNfcHVwX2J5X3ZhbCtnZ3NpZGU6Omdlb21feXNpZGVkZW5zaXR5KGFlcyh4PXN0YXQoZGVuc2l0eSksZmlsbCA9IG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSksIGFscGhhID0gLjQpCiAgCiAgCmdnTWFyZ2luYWwoYXJvdXNfcHVwX2J5X3ZhbCwgdHlwZSA9ICJkZW5zaXR5IikKYGBgCgpjZWlsaWluZyBlZmZlY3Q/CgpgYGB7cn0KZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIGdyb3VwX2J5KHNzaWQsIHN0aW1JQVBTLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbF9jLCBwdXBfYmFzQ29yKSkrCiAgICAgIGdlb21fcG9pbnQoKSsKICAgICMgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgcCRncmFwaHN0eWxlKwogIHhsYWIoIkFyb3VzYWwiKSsKICB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkrCiAgeWxpbSgtMy4zLDEuMykKCgpgYGAKCmNlaWxpbmcgZWZmZWN0PwpgYGB7cn0KZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIG11dGF0ZShwdXBfYmFzQ29yX21lYW4gPSBtZWFuKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHNkX3B1cCA9IHNkKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHN1YmogPSBuKCkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgcHVwX2Jhc0NvcikpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjQsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIyBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgeWxpbSgtMy4zLDEuMykKICAKICAKYGBgCiAgCiAgCmBgYHtyfSAgCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIG11dGF0ZShwdXBfYmFzQ29yX21lYW4gPSBtZWFuKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHNkX3B1cCA9IHNkKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHN1YmogPSBuKCkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgcHVwX2Jhc0NvcikpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjQsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIyBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgeWxpbSgtMy4zLDEuMykKICAKICAKICAKICAKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgIyBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAjIG11dGF0ZShwdXBfYmFzQ29yX21lYW4gPSBtZWFuKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHNkX3B1cCA9IHNkKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHN1YmogPSBuKCkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgIyBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAjIG11dGF0ZShwdXBfYmFzQ29yX3NlID0gc2RfcHVwLyhzcXJ0KHN1YmopKSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSwgcHVwX2Jhc0NvcikpKwogIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCwgY29sb3IgPSBGQUxTRSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjUsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwoKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIyBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgeWxpbSgtMy4zLDEuMykKICAKICAKICAKYGBgCgoKYGBge3J9CgojIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkYXJvdXNhbF9vdXRsZXIKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3Jfc2UgPSBzZF9wdXAvKHNxcnQoc3ViaikpKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBhcm91c2FsKSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogIHN0YXRfc3VtbWFyeSggZ2VvbSA9ICdwb2ludHJhbmdlJywgYWxwaGEgPSAuNSwgc2l6ZSA9IDEsIGNvbG91ciA9ICJCbGFjayIpICsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgIyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gcHVwX2Jhc0Nvcl9tZWFuLXB1cF9iYXNDb3Jfc2UsIHltYXggPSBwdXBfYmFzQ29yX21lYW4rcHVwX2Jhc0Nvcl9zZSApKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJWYWxlbmNlIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgoKIyBzdGltCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIGdyb3VwX2J5KHN0aW1JQVBTLCBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UsIG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zZWxmX2Fyb3VzYWwsIGFyb3VzYWwpKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KCBnZW9tID0gJ3BvaW50cmFuZ2UnLCBhbHBoYSA9IC41LCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCiAgIyBncm91bmQKICAKICAjIHN0aW0KICAKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMsIG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgQXJvdXNhbE1lYW4pKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KCBnZW9tID0gJ3BvaW50cmFuZ2UnLCBhbHBoYSA9IC41LCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgoKYGBgCiAgCiAgCiAgICAKCgpvdGVociBjb25mb3VuZHMgLSBleWUgbW92ZW1lbnRzCgpgYGB7cn0KZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQoc3NpZDwgNTAwKSU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9tZWFuID0gbWVhbihwdXBfYmFzQ29yLCBuYS5ybSA9IFRSVUUpLCBzZF9wdXAgPSBzZChwdXBfYmFzQ29yLCBuYS5ybSA9IFRSVUUpLCBzdWJqID0gbigpKSU+JQogIGdyb3VwX2J5KHNzaWQsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgIyBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAjIG11dGF0ZShwdXBfYmFzQ29yX3NlID0gc2RfcHVwLyhzcXJ0KHN1YmopKSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBtZWFuX2ZpeF9kdXIpKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgIyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gcHVwX2Jhc0Nvcl9tZWFuLXB1cF9iYXNDb3Jfc2UsIHltYXggPSBwdXBfYmFzQ29yX21lYW4rcHVwX2Jhc0Nvcl9zZSApKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJWYWxlbmNlIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICMgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIHlsaW0oLTMuMywxLjMpCiAgCiAgCiAgCiAgIHVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JFZhbGVuY2VNZWFuVGhpc1NhbXBsZSkKICAgCiAgIAogICBtZWRpYW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRWYWxlbmNlTWVhblRoaXNTYW1wbGUpCiAgICBtZWRpYW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCR2YWxlbmNlKQogICAgCiAgICAKICAgICBtZWRpYW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRhcm91c2FsKQogICAgbWVkaWFuKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkQXJvdXNhbE1lYW5UaGlzU2FtcGxlKQogIAogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KHNzaWQ8IDUwMCklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3JfbWVhbiA9IG1lYW4ocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc2RfcHVwID0gc2QocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc3ViaiA9IG4oKSklPiUKICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3Jfc2UgPSBzZF9wdXAvKHNxcnQoc3ViaikpKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlLCBtZWFuX2ZpeF9kdXIpKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgIyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gcHVwX2Jhc0Nvcl9tZWFuLXB1cF9iYXNDb3Jfc2UsIHltYXggPSBwdXBfYmFzQ29yX21lYW4rcHVwX2Jhc0Nvcl9zZSApKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJWYWxlbmNlIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICMgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIHlsaW0oLTMuMywxLjMpCiAgCmBgYAoKYGBge3J9CiAgIyBkYXRhIGxvc3MgZ2F6ZQogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KHNzaWQ8IDUwMCklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3JfbWVhbiA9IG1lYW4ocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc2RfcHVwID0gc2QocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc3ViaiA9IG4oKSklPiUKICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgZml4X2NvdW50KSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAjIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICB5bGltKC0zLjMsMS4zKQogIAogIAogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KHNzaWQ8IDUwMCklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3JfbWVhbiA9IG1lYW4ocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc2RfcHVwID0gc2QocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc3ViaiA9IG4oKSklPiUKICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgU2FjQW1wKSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAjIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICB5bGltKC0zLjMsMS4zKQogIAogIAogIAogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyPT0gRkFMU0UpJT4lCiAgc3Vic2V0KHNzaWQ8IDUwMCklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3JfbWVhbiA9IG1lYW4ocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc2RfcHVwID0gc2QocHVwX2Jhc0NvciwgbmEucm0gPSBUUlVFKSwgc3ViaiA9IG4oKSklPiUKICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgZ3JvdXBfYnkobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl9zZSA9IHNkX3B1cC8oc3FydChzdWJqKSkpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgc2RldmdhemUpKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgIyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gcHVwX2Jhc0Nvcl9tZWFuLXB1cF9iYXNDb3Jfc2UsIHltYXggPSBwdXBfYmFzQ29yX21lYW4rcHVwX2Jhc0Nvcl9zZSApKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJWYWxlbmNlIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICMgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIHlsaW0oLTMuMywxLjMpCiAgCiAgCiBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgIyBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAjIG11dGF0ZShwdXBfYmFzQ29yX21lYW4gPSBtZWFuKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHNkX3B1cCA9IHNkKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHN1YmogPSBuKCkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3Jfc2UgPSBzZF9wdXAvKHNxcnQoc3ViaikpKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIGdhemVfbG9zc19wcm9wKSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogICMgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IHB1cF9iYXNDb3JfbWVhbi1wdXBfYmFzQ29yX3NlLCB5bWF4ID0gcHVwX2Jhc0Nvcl9tZWFuK3B1cF9iYXNDb3Jfc2UgKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigiVmFsZW5jZSIpKwogICMgeWxhYigiQmFzZWxpbmUgY29ycmVjdGVkIHB1cGlsIikrCgogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAjIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICB5bGltKC0zLjMsMS4zKQogIAogIAogIAogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgIyBncm91cF9ieShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAjIG11dGF0ZShwdXBfYmFzQ29yX21lYW4gPSBtZWFuKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHNkX3B1cCA9IHNkKHB1cF9iYXNDb3IsIG5hLnJtID0gVFJVRSksIHN1YmogPSBuKCkpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogICMgbXV0YXRlKHB1cF9iYXNDb3Jfc2UgPSBzZF9wdXAvKHNxcnQoc3ViaikpKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIHRvdGFsX2ZpeF9kdXIpKSsKICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQsIGNvbG9yID0gRkFMU0UpKwogICAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYT0uMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIGFscGhhID0gLjEsIHNpemUgPSAxLCBjb2xvdXIgPSAiQmxhY2siKSArCiAgIyBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gcHVwX2Jhc0Nvcl9tZWFuLXB1cF9iYXNDb3Jfc2UsIHltYXggPSBwdXBfYmFzQ29yX21lYW4rcHVwX2Jhc0Nvcl9zZSApKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJWYWxlbmNlIikrCiAgIyB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICMgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIAogIApgYGAKCiMgbGV0J3MgbW9kZWwgaXQgZm9ybWFsbHkKICAKIyByZW1lbWJlciBiYXNlbGluZSBjb3JlY3Rpb24gaXMgZXF1aXZhbGVuZHQgdG8gc3RpbXVsaSBpbnRlcmNlcHQKIApgYGB7cn0gCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3M8LSBsaXN0KCkKbGlicmFyeShsbWVyVGVzdCkKCnVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JHN0aW1JQVBTKQp1bmlxdWUoc3Vic3RyKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3Qkc3RpbUlBUFMsIDEsOCkpCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkTGFiZWw8LSBzdWJzdHIoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRzdGltSUFQUywgMSw4KQogIApkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0PC0gbGVmdF9qb2luKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIGltYWdlSl9JQVBTLCBieSA9ICJMYWJlbCIpCm5yb3coZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCkKIyByb3dzID0gMjg1OAoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRNZWFuX2dyYXlfejwtIHNjYWxlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkTWVhbiwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0KCm9wdGlvbnMoY29udHJhc3RzID0gYygiY29udHIuc3VtIiwiY29udHIucG9seSIpKQpvcHRpb25zKHNjaXBlbiA9IDk5OSkKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3Qkc3NpZF9udW0gPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRzc2lkKSkKCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcm91c2FsIDwtIGxtZXIocHVwX2Jhc0NvciB+IGFyb3VzYWxfYypNZWFuX2dyYXlfeiAgKygxICtNZWFuX2dyYXlfeiB8IHNzaWQpICsgKDArYXJvdXNhbF9jfCBzc2lkKSwgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgc3NpZF9udW08IDUwMCAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFKSkKCnN1bW1hcnkocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2Fyb3VzYWwpCiMgc2luZ3VsYXJpdHkgKGRyb3AgYXJvdXNhbCBjIHNsb3BlKQoKIyBpcyB0aGVyZSBhIGNvb3JlbGF0aW9uYnR3ZWVuIG1lYW4gYXJvdXNhbCByYXRpbmcgYW5kIG1lYWdyYXkoCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMsZ3JvdW5kX3ZhbGVuY2VfbGFiKSAlPiUKICBzdW1tYXJpc2VfYXQoYygnYXJvdXNhbF9jJywgJ01lYW5fZ3JheV96JyksIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGFyb3VzYWxfYywgTWVhbl9ncmF5X3osIGNvbG9yID0gZ3JvdW5kX3ZhbGVuY2VfbGFiKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCiMgPC0gcHJlZGljdChwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJvdXNhbCkKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBncm91cF9ieShzdGltSUFQUykgJT4lCiAgIyBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICMgc3VtbWFyaXNlX2F0KGMoJ2Fyb3VzYWxfYycsICdNZWFuX2dyYXlfeicpLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhhcm91c2FsX2MsIHB1cCkpKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHNzaWQsIGFscGhhID0gc3NpZCksIG1ldGhvZCA9ICdsbScsIHNlID0gRikKIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBzdGltSUFQUyksIG1ldGhvZCA9ICdsbScsIHNlID0gRikKICBnZ3B1YnI6OnN0YXRfY29yKCkKCgpgYGAKY29yLnRlc3QoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCQsIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkKQoKCmBgYHtyfQojIGlmIHdlIHB1dCBicmlnaHRlbmVzcyBhbmQgYXJvdXNhbCB3ZSBzZWUgbm8gaW50ZXJhY3Rpb24gd2hpY2ggbWVhbnMgd2UgcHJvYmFibHkgZG9uJ3QgbmVlZCB0byB3b3JyeSBhYm91dCBicmlnaHRlbmVzcywgaXQgZG9lc24ndCBjaGFuZ2UgZWZmZWN0cyBvZiBhcm91c2FsIHNlbGYgcmVwb3J0CiMgZGJfZnVsbDRuZXdfc3RpbV9wdXBpbCRwdXAKcHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2Fyb3VzYWwgPC0gbG1lcihwdXBfYmFzQ29yIH4gYXJvdXNhbF9jK01lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCksIFJFTUwgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRwdXAsIHB1cGlsX291dGxpZXIgPT0gRkFMU0UgJiBzc2lkX251bTwgNTAwJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm91c2FsX291dGxlciA9PSBGQUxTRSkpCgppbnN0YWxsLnBhY2thZ2VzKCd1c2RtJykKCnVzZG06OnZpZihhcy5kYXRhLmZyYW1lKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RbLGMoJ2Fyb3VzYWwnLCAndmFsZW5jZScpXSkpCgpwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJvdXNhbF93aXRodmFsIDwtIGxtZXIocHVwX2Jhc0NvciB+IGFyb3VzYWxfYyp2YWxlbmNlX2MqIE1lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCksIFJFTUwgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCwgcHVwaWxfb3V0bGllciA9PSBGQUxTRSAmIHNzaWRfbnVtPCA1MDAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFKSkKCnN1bW1hcnkocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2Fyb3VzYWxfd2l0aHZhbCkKY2FyOjp2aWYocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2Fyb3VzYWxfd2l0aHZhbCkKCmxtZXJUZXN0OjpzdGVwKHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcm91c2FsX3dpdGh2YWwpCgoKCiMgY29udHJvbCBmb3IgYmFzZWxpbmUgYXJvdXNhbCByYXRpbmdzCgpwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJvdXNhbF93aXRodmFsCgpzdW1tYXJ5KGxtZXIocHVwX2Jhc0NvciB+IGFyb3VzYWxfYyp2YWxlbmNlX2MrIE1lYW5fZ3JheV96ICArKDEgfCBzc2lkKSArICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgIyAoMXxBcm91c2FsTWVhbikrICgxfEFyb3VzYWxNZWFuKSwgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgR3JvdXAgPT0gIk5UIiAgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm91c2FsX291dGxlciA9PSBGQUxTRSkpKQoKCgojIGFyb3VzYWxfYzp2YWxlbmNlX2MgICAgICAgICAgICAgICAgICAgICAgMCAgMzUuNTIgICAzNS41MiAgICAgMSAyMTUwLjE5ICAxMy41NzYwIDAuMDAwMjM0OCAqKioKCgpwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJGFyb3VzYWxfZnJvbV9wdXBpbCA8LSBsbWVyKGFyb3VzYWwgfiBwdXBfYmFzQ29yICogTWVhbl9ncmF5X3ogICsoMStwdXBfYmFzQ29yICB8IHNzaWQpLCBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIHB1cGlsX291dGxpZXIgPT0gRkFMU0UgJiBzc2lkIT0gNjEwJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm91c2FsX291dGxlciA9PSBGQUxTRSkpCgpzdW1tYXJ5KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdXNhbF9mcm9tX3B1cGlsKQojIHdoYXQgYWJvdXQgdmFsZW5jZQoKcHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX3ZhbGVuY2UgPC0gbG1lcihwdXBfYmFzQ29yIH4gdmFsZW5jZV9jK01lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgwICt2YWxlbmNlX2MgfCBzc2lkKSwgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgc3NpZCE9IDYxMCYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpKQoKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJvdXNhbCkKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fdmFsZW5jZSkKCgpgYGAKCgojIFZhbGVuY2UgYW5kIGFyb3VzYWwKYGBge3J9CgpwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJfdmFsZSA8LSBsbWVyKHB1cF9iYXNDb3IgfiAodmFsZW5jZV9jKiBhcm91c2FsX2MpICsgTWVhbl9ncmF5X3ogICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDArIHZhbGVuY2VfYyogYXJvdXNhbF9jIHwgc3NpZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgc3NpZF9udW08IDUwMCAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFKSkKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkdG90YWxfZml4X2R1cl96PC0gc2NhbGUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCR0b3RhbF9maXhfZHVyLCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpWywxXQoKcHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2FyX3ZhbF9nYXplIDwtIGxtZXIocHVwX2Jhc0NvciB+ICh2YWxlbmNlX2MgKiBhcm91c2FsX2MgKiB0b3RhbF9maXhfZHVyX3opKyBNZWFuX2dyYXlfeiAgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDArICB0b3RhbF9maXhfZHVyX3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIHB1cGlsX291dGxpZXIgPT0gRkFMU0UgJiBzc2lkX251bTwgNTAwICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpKQoKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJfdmFsX2dhemUgKQpzdW1tYXJ5KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxlKQoKCmNhcjo6dmlmKHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxfZ2F6ZSkKCmFub3ZhKHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxlLCBwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJvdXNhbCkKIyBpbnRlcmFjdGlvbiB2YWxlbmNlIGFuZCBhcm91c2FsCgoKCmBgYAoKCgpjb250cm9sIGZvciBnYXplCgpgYGB7cn0KIyBhdmcgZml4IGR1cgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JG1lYW5fZml4X2R1cl96PC0gc2NhbGUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRtZWFuX2ZpeF9kdXIsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSlbLDFdCgpwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJfdmFsX2dhemUgPC0gbG1lcihwdXBfYmFzQ29yIH4gKHZhbGVuY2VfYyAqIGFyb3VzYWxfYyAqIG1lYW5fZml4X2R1cl96KSsgTWVhbl9ncmF5X3ogICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSArIE1lYW5fZ3JheV96IHwgc3NpZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICgwKyAgdG90YWxfZml4X2R1cl96IHwgc3NpZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgc3NpZF9udW08IDUwMCAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFKSkKCnN1bW1hcnkocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2FyX3ZhbF9nYXplICkKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxfZ2F6ZSAsIHByZWQgPSBhcm91c2FsX2MsIG1vZHggPSBtZWFuX2ZpeF9kdXJfeikKCgojIGZpeCBjb3VudAoKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkZml4X2NvdW50X3o8LSBzY2FsZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JGZpeF9jb3VudCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0KCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxfZ2F6ZSA8LSBsbWVyKHB1cF9iYXNDb3IgfiAodmFsZW5jZV9jICogYXJvdXNhbF9jICogZml4X2NvdW50X3opKyBNZWFuX2dyYXlfeiAgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDArICB0b3RhbF9maXhfZHVyX3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIHB1cGlsX291dGxpZXIgPT0gRkFMU0UgJiBzc2lkX251bTwgNTAwICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpKQoKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJfdmFsX2dhemUgKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxfZ2F6ZSAsIHByZWQgPSBhcm91c2FsX2MsIG1vZHggPSBtZWFuX2ZpeF9kdXJfeikKYGBgCgoKYGBge3J9CmludGVyYWN0aW9uczo6aW50ZXJhY3RfcGxvdChwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJHB1cGlsX2Zyb21fYXJfdmFsZSAsIHByZWQgPSB2YWxlbmNlX2MsIG1vZHggPSBhcm91c2FsX2MpCgppbnRlcmFjdGlvbnM6OmludGVyYWN0X3Bsb3QocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRwdXBpbF9mcm9tX2FyX3ZhbGUgLCBwcmVkID1hcm91c2FsX2MgLCBtb2R4ID0gIHZhbGVuY2VfYykKCmNhcjo6dmlmKHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkcHVwaWxfZnJvbV9hcl92YWxlKSAjY3Vyb2ZmIDIuNT8KCmNvci50ZXN0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkdmFsZW5jZV9jLCBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JGFyb3VzYWxfYykKCnJtY29ycl92YWxlbmNlX2Fyb3VzYWwgPC0gcm1jb3JyOjpybWNvcnIocGFydGljaXBhbnQgPSAic3NpZCIsIG1lYXN1cmUxID0gInZhbGVuY2VfYyIsIG1lYXN1cmUyID0gImFyb3VzYWxfYyIsIGRhdGEgPSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0KQoKcGxvdChybWNvcnJfdmFsZW5jZV9hcm91c2FsKQoKP3JtY29ycgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBncm91cF9ieShzdGltSUFQUyklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoQXJvdXNhbE1lYW4sIFZhbGVuY2VNZWFuKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpKwogIHRoZW1lX2NsYXNzaWMoKQoKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGFyb3VzYWxfYywgdmFsZW5jZV9jKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpKwogIHRoZW1lX2NsYXNzaWMoKQoKYGBgCgoKCgoKYGBge3J9CiMgd2l0aCBhcm91c2FsIGFzIERWCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdWFsX2Zyb21fcHVwIDwtIGxtZXIoYXJvdXNhbCB+IHZhbGVuY2VfYypwdXBfYmFzQ29yICogIEJSSUdIVE5FU1NjICArICgxfCBzdGltSUFQUykrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHNzaWQpKygwICt2YWxlbmNlX2MgfCBzc2lkKSwgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgc3NpZCE9IDYxMCYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpKQpzdW1tYXJ5KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdWFsX2Zyb21fcHVwKQoKYW5vdmEocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRhcm91YWxfZnJvbV9wdXApCgoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdWFsX2Zyb21fcHVwICwgcHJlZCA9IHZhbGVuY2VfYywgbW9keCA9IHB1cF9iYXNDb3IpCgppbnRlcmFjdGlvbnM6OmludGVyYWN0X3Bsb3QocHVwaWxfYXJvdXNhbF9maW5kaW5ncyRhcm91YWxfZnJvbV9wdXAsIHByZWQgPXB1cF9iYXNDb3IgLCBtb2R4ID0gIHZhbGVuY2VfYykKIyBmb3IgcG9zaXRpdmUgdmFsZW5jZWQgc3RpbXVsaSBwYXJ0aWNpcGFudHMgcmVwb3J0ZSBoaWdoZXIgYXJvdXNhbCB0byBtb3JlIGRpbGF0ZWQgcHVwaWxzCiNmb3IgbmVnYXRpdmVseSB2YWxlbmNlIHRoZXkgcmVwb3J0IGZlZWxpbmcgbmVnYXRpdmUgZXZlbiB3aGVuIHRoZXkgZG9uJ3Qgc2hvdyBzdHJvZyBwdXBpbCBkaWxhdGlvbgojIHNhbWUgcGF0dGVybgojIHB1cGlsIGlzIG1vcmUgYWxpZ2huZWQgd2l0aCBvYmplY3RpdmUgYXJvdXNhbCBpbiB0aGUgcG9zaXRpdmUgdHJpYWxzCgpgYGAKCm1peGVkIG1vZGVsIGlzIGNvbnNpc3RlbnQgd3RoIHRoZSBwcmV2aW91cyBwbG90LCBhcm91c2FsIGVmZmVjdHMgb24gcHVwaWwgaXMgbW9kdWxhdGVkIGJ5IHZhbGVuY2UuIGluIG90aGVyIHdvcmRzIHRoZXJlIGlzIGEgY29uc2lzdGVudCBlZmZlY3QgYmV0d2VlbiBwdXBpbCBhbmQgc2VsZi1yZXBvdCBvZiBhcm91c2FsIG1vcmUgZm9yIHBvc2l0aXZlIGVtb3Rpb25zLgoKCmFuYWx5c2UgdGhlIGNvcnJlbGF0aW9ubGEgd2F5CnNpbmNlIHdlIGFyZSBhZ2dyZWdhdGluZyB3ZSBkb24ndCBuZWVkIHRvIHdvcnJ5IHRvbyBtdWNoIGFib3V0IGJyaWdodGVuZXNzIGFzIGV2ZXJ5IHBlcnNvbiBzZWVzIGV2ZXJ5IHN0aW11bGkgaW4gYWxsIGJyaWdodG5lc3MgbGV2ZWxzCkNPTkNPUkRBTkNFCgpgYGB7cn0KCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QlPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2VfdGhpc3NhbXBsZSwgc3RpbUlBUFMpJT4lCiAgc3VtbWFyaXNlX2F0KGMoImFyb3VzYWwiLCAndmFsZW5jZScpLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgYXJyYW5nZShzdGltSUFQUykKCgoKYGBgCgpgYGBge3J9Cgp0ZXN0X2Fub3ZhczwtIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSAmICFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgaXNfdmFsZW5jZV9oaWdoKSU+JQogICBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSU+JQogICAgbXV0YXRlKGNvcnRlc3QgPSBjb3IoYXJvdXNhbF9jLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpCgoKIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSAmICFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgaXNfdmFsZW5jZV9oaWdoKSU+JQogICBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSU+JQogICAgbXV0YXRlKGNvcnRlc3QgPSBjb3IoYXJvdXNhbF9jLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsIGNvcnRlc3QsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40KSsKICAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogICAgICAgIHN0YXRfc3VtbWFyeSggZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICAgICAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAuMSkrCiAgICB5bGFiKCJSIHB1cGlsIHZzIHNlbGYgcmVwb3J0IGFyb3VzYWwiKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIGFscGhhID0gLjIpKwogICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUpKwogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKCkrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKQogIAogIAogIAogIAogICMgbGV0J3MgaWRlbnRpZnkgdGhlIGZvbGtzIHRoYXQgc2hvdyBsZXNzIG9mIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIGNvbmRpdGlvbnMuCgpmbGFnX3Bvc19uZWc8LSAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFICYgIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogICAgIyBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBpc192YWxlbmNlX2hpZ2gpJT4lCiAgIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiklPiUKICAgIG11dGF0ZShjb3J0ZXN0ID0gY29yLnRlc3QoYXJvdXNhbF9jLCBwdXBfYmFzQ29yKSRlc3RpbWF0ZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICBtdXRhdGUoY29yX3Bvc19uZWdfZGlmZiA9IGNvcnRlc3RbbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyID09ICJNb3JlIHBvc2l0aXZlIl0gLQogICAgICAgICAgICAgY29ydGVzdFttZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIgPT0gIk1vcmUgbmVnYXRpdmUiXSklPiUKICAgIG11dGF0ZShjb3JfcG9zX25lZ19kaWZmX2xhYiA9IGlmX2Vsc2UoY29yX3Bvc19uZWdfZGlmZj4wLCAicG9zID4gbmVnIiwgIm5lZyA+IHBvcyIpKSU+JQogICAgIGdyb3VwX2J5KHNzaWQsY29yX3Bvc19uZWdfZGlmZl9sYWIpJT4lCiAgICBzdW1tYXJpc2VfYXQoYygiY29yX3Bvc19uZWdfZGlmZiIpLCBtZWFuLCBuYS5ybSA9IFRSVUUpCiAgICAKICAgIAogICAgIyBzdWJzZXQoY29yX3Bvc19uZWdfZGlmZjw9IDApJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsIGNvcnRlc3QsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40KSsKICAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogICAgICAgIHN0YXRfc3VtbWFyeSggZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICAgICAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAuMSkrCiAgICB5bGFiKCJSIHB1cGlsIHZzIHNlbGYgcmVwb3J0IGFyb3VzYWwiKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIGFscGhhID0gLjIpCiAgICMgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gVFJVRSkrCiAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKQogIApgYGAKCgpgYGB7cn0KdGVzdGNvciA8LWNvcihkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JGFyb3VzYWwsIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkdmFsZW5jZSkgCiAgCnRlc3Rjb3IgCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSAmICFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgaXNfdmFsZW5jZV9oaWdoKSU+JQogICBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsIG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiklPiUKICAgICMgbXV0YXRlKGNvcnRlc3QgPSBjb3IudGVzdChhcm91c2FsX2MsIHB1cF9iYXNDb3IpJGVzdGltYXRlKSU+JQogICBtdXRhdGUoY29ydGVzdCA9IGNvcihhcm91c2FsX2MsIHB1cF9iYXNDb3IsIG1ldGhvZCA9ICdrZW5kYWxsJykpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICAgICAgIGdncGxvdChhZXMobWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLCBjb3J0ZXN0LCBjb2xvciA9IG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCkrCiAgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYSA9IC4xKSsKICAgICAgICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScpKwogICAgICAgICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gLjEpKwogICAgeWxhYigiUiBwdXBpbCB2cyBzZWxmIHJlcG9ydCBhcm91c2FsIikrCiAgdGhlbWVfY2xhc3NpYygpKwogICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4yLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC4yKQogICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUpKwogICMgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKQogIAogIAoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFICYgIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogICAgIyBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBpc192YWxlbmNlX2hpZ2gpJT4lCiAgIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiwgbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKSU+JQogICAgIyBtdXRhdGUoY29ydGVzdCA9IGNvci50ZXN0KGFyb3VzYWxfYywgcHVwX2Jhc0NvcikkZXN0aW1hdGUpJT4lCiAgIG11dGF0ZShjb3J0ZXN0ID0gY29yKHZhbGVuY2VfYywgcHVwX2Jhc0NvciwgbWV0aG9kID0gJ2tlbmRhbGwnKSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIsIGNvcnRlc3QsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40KSsKICAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogICAgICAgIHN0YXRfc3VtbWFyeSggZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICAgICAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAuMSkrCiAgICB5bGFiKCJSIHB1cGlsIHZzIHNlbGYgcmVwb3J0IGFyb3VzYWwiKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjIsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIGFscGhhID0gLjIpCgpgYGAKICAKCiMgc2FtZSBhcyBwbG90IGFib3ZlIGJ1dCB3aXRoIHZhbGVuY2UgaW4gdGhlIGNvcnJlbGF0aW9uCmBgYHtyfQpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCggYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgJiAhaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldChzc2lkX251bTw1MDApJT4lCiAgICAjIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIGlzX3ZhbGVuY2VfaGlnaCklPiUKICAgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSU+JQogICAgbXV0YXRlKGNvcnRlc3QgPSBjb3IudGVzdCh2YWxlbmNlX2MsIHB1cF9iYXNDb3IpJGVzdGltYXRlKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICAgICAgICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiwgY29ydGVzdCwgY29sb3IgPSBtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpKSsKICAgICAgICAgICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQpKwogIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGEgPSAuMSkrCiAgICAgICAgc3RhdF9zdW1tYXJ5KCBnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICAgICAgICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IC4xKSsKICAgIHlsYWIoIlIgcHVwaWwgdnMgc2VsZiByZXBvcnQgYXJvdXNhbCIpKwogIHRoZW1lX2NsYXNzaWMoKQogICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUpKwogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKCkKICAKICAKYGBgCiAgCmBgYHtyfQojIGdyb3VuZAoKIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSAmICFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgaXNfdmFsZW5jZV9oaWdoKSU+JQogICBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAgIG11dGF0ZShjb3J0ZXN0ID0gY29yLnRlc3QoYXJvdXNhbF9jLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSRlc3RpbWF0ZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgY29ydGVzdCwgY29sb3IgPSBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCkrCiAgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYSA9IC4zKSsKICAgICAgICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScpKwogICAgICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IC4xKSsKICAgIHlsYWIoIlIgcHVwaWwgdnMgc2VsZiByZXBvcnQgYXJvdXNhbCIpKwogICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUpKwogICMgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKQogICB0aGVtZV9jbGFzc2ljKCkKYGBgCiAKCgpgYGB7cn0KICMgZ3JvdW5kIGFyb3VzYWwgd2l0aCB2YWxlbmNlIGluIHRoZSAgY29yZWxhdGlvbgogCiBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCggYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgJiAhaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldChzc2lkX251bTw1MDApJT4lCiAgICAjIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIGlzX3ZhbGVuY2VfaGlnaCklPiUKICAgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgICBtdXRhdGUoY29ydGVzdCA9IGNvci50ZXN0KHZhbGVuY2VfYywgcHVwX2Jhc0NvciwgdXNlID0gImNvbXBsZXRlIikkZXN0aW1hdGUpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogICAgICAgIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIGNvcnRlc3QsIGNvbG9yID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSsKICAgICAgICAgICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjQpKwogIAogICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGEgPSAuMykrCiAgICAgICAgc3RhdF9zdW1tYXJ5KCBnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICAgICAgICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAuMSkrCiAgICB5bGFiKCJSIHB1cGlsIHZzIHNlbGYgcmVwb3J0IGFyb3VzYWwiKSsKICAgIyBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBUUlVFKSsKICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKCkKICAgdGhlbWVfY2xhc3NpYygpCgoKCgogZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFICYgIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogICAgIyBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBpc192YWxlbmNlX2hpZ2gpJT4lCiAgIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCklPiUKICAgIG11dGF0ZShjb3J0ZXN0ID0gY29yLnRlc3QoYXJvdXNhbF9jLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSRlc3RpbWF0ZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgY29ydGVzdCwgY29sb3IgPSBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuNCkrCiAgCiAgICBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYSA9IC4zKSsKICAgICAgICBzdGF0X3N1bW1hcnkoIGdlb20gPSAncG9pbnRyYW5nZScpKwogICAgICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IC4xKSsKICAgIHlsYWIoIlIgcHVwaWwgdnMgc2VsZiByZXBvcnQgYXJvdXNhbCIpKwogICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUpKwogICMgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKQogICB0aGVtZV9jbGFzc2ljKCkrCiAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsKQoKYGBgCgogCmBgYHtyfQpkYl9wdXBpbF9jb25jb3JkYW5jZV9hZ2dfZ3JvdW5kIDwtICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFKSU+JQogIHN1YnNldCggYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgJiAhaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogIHN1YnNldChzc2lkX251bTw1MDApJT4lCiAgICAjIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIGlzX3ZhbGVuY2VfaGlnaCklPiUKICAgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgICBtdXRhdGUoY29ydGVzdCA9IGNvci50ZXN0KGFyb3VzYWxfYywgcHVwX2Jhc0NvciwgdXNlID0gImNvbXBsZXRlIikkZXN0aW1hdGUpJT4lCiAgICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKQoKYWZleDo6YW92X2V6KGlkID0gInNzaWQiLAogICAgICAgICAgICAgZGF0YSA9IGRiX3B1cGlsX2NvbmNvcmRhbmNlX2FnZywKICAgICAgICAgICAgIGJldHdlZW4gPSBOVUxMLAogICAgICAgICAgICAgd2l0aGluID0gJ21lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlJywKICAgICAgICAgICAgIGR2ID0gJ2NvcnRlc3QnKQoKCnVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JHRObykKZGJfcHVwaWxfY29uY29yZGFuY2VfYWdnX3NlbGYgPC0gIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSAmICFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgIyBzdWJzZXQoR3JvdXAgPT0gIk5UIiklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogICAgIyBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBpc192YWxlbmNlX2hpZ2gpJT4lCiAgIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbCwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSU+JQogICAgbXV0YXRlKGNvcnRlc3QgPSBjb3IoYXJvdXNhbF9jLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpCgphZmV4Ojphb3ZfZXooaWQgPSAic3NpZCIsCiAgICAgICAgICAgICBkYXRhID0gdGVzdF9hbm92YXMsCiAgICAgICAgICAgICBiZXR3ZWVuID0gTlVMTCwKICAgICAgICAgICAgIHdpdGhpbiA9ICdtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTInLAogICAgICAgICAgICAgZHYgPSAnY29ydGVzdCcpCgoKYWZleDo6YW92X2V6KGlkID0gInNzaWQiLAogICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0ZXN0X2Fub3ZhcywgbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyID09ICJNb3JlIHBvc2l0aXZlIiksCiAgICAgICAgICAgICBiZXR3ZWVuID0gTlVMTCwKICAgICAgICAgICAgIHdpdGhpbiA9ICdtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDInLAogICAgICAgICAgICAgZHYgPSAnY29ydGVzdCcpCgoKYWZleDo6YW92X2V6KGlkID0gInNzaWQiLAogICAgICAgICAgICAgZGF0YSA9IGRiX3B1cGlsX2NvbmNvcmRhbmNlX2FnZ19zZWxmLAogICAgICAgICAgICAgYmV0d2VlbiA9IE5VTEwsCiAgICAgICAgICAgICB3aXRoaW4gPSAnbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UnLAogICAgICAgICAgICAgZHYgPSAnY29ydGVzdCcpCgojIHZhbGVuY2UgYW5kIGFyb3VzYWwKCgphZmV4Ojphb3ZfZXooaWQgPSAic3NpZCIsCiAgICAgICAgICAgICBkYXRhID0gdGVzdF9hbm92YXMsCiAgICAgICAgICAgICBiZXR3ZWVuID0gTlVMTCwKICAgICAgICAgICAgIHdpdGhpbiA9IGMoJ21lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMicsJ21lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMicpLAogICAgICAgICAgICAgZHYgPSAnY29ydGVzdCcpCgoKCgoKZGJfcGFyc2VkX2Zfc3VtbTwtIGRiX3BhcnNlZF9mICU+JQogIGdyb3VwX2J5KHRObywgc3NpZCklPiUKICBzdW1tYXJpc2VfYXQoYygnRHVyYXRpb24nLCAnbWVhbl94JywgJ21lYW5feScpLCBzdW0sIG5hLnJtID0gVFJVRSkKICBnZ3Bsb3QoYWVzKHRObywgRHVyYXRpb24pKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgZ2VvbV9wb2ludChhbHBoYSA9IC4xKQoKCnVuaXF1ZShkYl9wYXJzZWRfZl9zdW1tJHNzaWQpCnVuaXF1ZShkYl9wYXJzZWRfZl9zdW1tJHRObykKdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkdE5vKQp1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRzc2lkKQpucm93KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QpCm5yb3coZGJfcGFyc2VkX2Zfc3VtbSkKCnRhYmxlKGlzLm5hKGRiX3BhcnNlZF9mX3N1bW0kc3NpZCkpCgpkYl9wYXJzZWRfZl9zdW1tJHRvdGFsX2ZpeF9kdXI8LSBkYl9wYXJzZWRfZl9zdW1tJER1cmF0aW9uCgoKZGJfcGFyc2VkX2Zfc3VtbSR0Tm88LSBhcy5jaGFyYWN0ZXIoZGJfcGFyc2VkX2Zfc3VtbSR0Tm8pCmRiX3BhcnNlZF9mX3N1bW0kc3NpZDwtIGFzLmNoYXJhY3RlcihkYl9wYXJzZWRfZl9zdW1tJHNzaWQpCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkRHVyYXRpb248LSBOVUxMCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkdG90YWxfZml4X2R1cjwtIE5VTEwKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3Q8LSBsZWZ0X2pvaW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCwgZGJfcGFyc2VkX2Zfc3VtbSkKICAKYGBgCgoKSSBIQVZFIFRIRSBJTVBSRVNTSU9OIFRIQVQgV0hBVCBUSElTIEFOQUxZU0VTIEdJVkVTIFVTIElTIFRIRSBTQU1FIEFTIFRIRSBNSVhFRCBNT0RFTCBBUyBUSElTIENPTkNJT1JEQU5DRSBDQU4gQkUgRVhQUkVTU0VEIElOIFRFUk1TIEZPIFRIRSBTTE9QRSBPRiBUSEUgQU9VU0FMIEFORCBQVVBJTCBSRUxBVElPTgoKClNPIElPTiBPVEhFUiBXT1JEUyBJUyBub3QgdGhhdCBwdXBpbCB0cmFja3N2YWxlbmNlIGlzIHRoYXQgYXJvdXNhbCBiYXNlZCBwdXBpbCBpcyBtb2R1bGF0ZWQgYnkgdmFsZW5jZQoKYnkgd2h5IGlzIHRoYXQKLSBiaWFzIGlzIHJlc3BvbmRpbmc/IGVnLi4gcGVvcGxlIHJlc3BvbnNlIHRoZXkgZmVlbCBuZWdhdGl2ZSBldmVuIHdoZW4gdGhleSBkb24ndCAoaWUuIHdoZW4gd2UgaGF2ZSBubyBvYmplY3RpdmUgaW5kaWNhdG9yIHRoYXQgdGhleSBkbyBmZWVsKQotIGlzIGl0IHNvbWV0aGluZyBhYm91dCB0aGUgc3RpbXVsaSwgcG9zaXRpdmUgYXJvdXNhbCBpcyBzZXh1YWwgaGVyZT8KLSBvciBhcm91c2FsIGludGVyZmVyZXMgd2l0aCBhcHByYWlzYWwuIGhpZ2ggYXJvdXNpbmcgc3RpbXVsaSBhcmUgZGlzdHJhY3Rpbmc/PwoKCgp0aW1lY291cnNlIG1vZGVscyBvZiBwdXBpbAoKCgoKCgoKUHVwaWwgdHJhY2tzIHZhbGVuY2UKCmBgYHtyfQoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfQW5vcHJhY3QgJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKHB1cF9iYXNDb3JfeiA9IHNjYWxlKHB1cF9iYXNDb3IsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSkpJT4lCiAgICBncm91cF9ieShzc2lkLCBncm91bmRfdmFsZW5jZV9sYWIsIEFsZXhpdGh5bWlhKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGdyb3VuZF92YWxlbmNlX2xhYiwgcHVwX2Jhc0Nvcl96LGZpbGwgPSBncm91bmRfdmFsZW5jZV9sYWIpKSsKIGdlb21faGFsZl92aW9saW4oY29sb3VyID0gRkFMU0UsIGFscGhhID0gLjMsIHNpemUgPSA1KSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCB3aWR0aCA9MSkrCiAgICAjIGdlb21feXNpZGVkZW5zaXR5KGFlcyh4PXN0YXQoZGVuc2l0eSksY29sb3IgPSBncm91bmRfdmFsZW5jZV9sYWIpLCBhbHBoYSA9IC40KSsKICBwJGdyYXBoc3R5bGUrCiAgeGxhYigidmFsZW5jZSIpKwogIHlsYWIoIkJhc2VsaW5lIGNvcnJlY3RlZCBwdXBpbCIpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKQoKCm1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZQoKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QgJT4lCiAgIyBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXI9PSBGQUxTRSklPiUKICBzdWJzZXQocHVwaWxfb3V0bGllciA9PSBGQUxTRSklPiUKICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBzdWJzZXQoc3NpZF9udW08NTAwKSU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgIyBtdXRhdGUocHVwX2Jhc0Nvcl96ID0gc2NhbGUocHVwX2Jhc0NvciwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKSklPiUKICAgIGdyb3VwX2J5KHNzaWQsIHNlbGZfYXJvdXNhbF9sYWIsIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhzZWxmX2Fyb3VzYWxfbGFiLCBwdXBfYmFzQ29yLGZpbGwgPSBzZWxmX2Fyb3VzYWxfbGFiKSkrCiBnZW9tX2hhbGZfdmlvbGluKGNvbG91ciA9IEZBTFNFLCBhbHBoYSA9IC4zLCBzaXplID0gNSkrCiAgICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhPS4yKSsKICAgIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJywgYWxwaGEgPSAuMSwgc2l6ZSA9IDEsIGNvbG91ciA9ICJCbGFjayIpICsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJywgd2lkdGggPTEpKwogICAgIyBnZW9tX3lzaWRlZGVuc2l0eShhZXMoeD1zdGF0KGRlbnNpdHkpLGNvbG9yID0gZ3JvdW5kX3ZhbGVuY2VfbGFiKSwgYWxwaGEgPSAuNCkrCiAgcCRncmFwaHN0eWxlKwogIHhsYWIoImFyb3VzYWwiKSsKICB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKQoKCgoKCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlcj09IEZBTFNFKSU+JQogIHN1YnNldChzc2lkPCA1MDApJT4lCiAgc3Vic2V0KHB1cGlsX291dGxpZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgICBncm91cF9ieShzc2lkLCBzZWxmX2Fyb3VzYWxfbGFiLCBBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKHNlbGZfYXJvdXNhbF9sYWIsIHB1cF9iYXNDb3IsIGNvbG9yID0gc2VsZl9hcm91c2FsX2xhYixmaWxsID0gc2VsZl9hcm91c2FsX2xhYikpKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIsIGFscGhhID0gLjIpKwogIyBnZW9tX2hhbGZfdmlvbGluKGNvbG91ciA9IEZBTFNFLCBhbHBoYSA9IC4zLCBzaXplID0gNSkrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC40LCBjb2xvciA9IEZBTFNFKSsKICAgICAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMSwgYWxwaGE9LjIpKwogICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4xLCBzaXplID0gMSwgY29sb3VyID0gIkJsYWNrIikgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnLCB3aWR0aCA9MSkrCiAgcCRncmFwaHN0eWxlKwogIHhsYWIoIkFyb3VzYWwiKSsKICB5bGFiKCJCYXNlbGluZSBjb3JyZWN0ZWQgcHVwaWwiKSsKCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSkKICAjIGZhY2V0X2dyaWQofkJSSUdIVE5FU1NfbWVkaWFuc3BsaXQpKwogIHlsaW0oLTYsMi4zKQogIAogIAogIAogIAogIAogIAp0YWJsZShpcy5uYShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSkpCmBgYAoKCgpjb21iaW5lIHRpbWVjb3Vyc2UKCgpsZXQncyBwdXQgcHVwaWwgc2NyIGFuZCBodCBwcmVkaWN0aW9uIG9uIHN1YmplY3RpdmUgYXJvdXNhbAoKCgpgYGB7cn0Kcm0oanVzdG9uZV90ZXN0LCBsdWN5X3Bsb3RzLCB0ZXN0KQoKIyBpbXBvcnQgdGhlIHRpbWVjb3Vyc2UKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjEgPC0gcmVhZFJEUygifi9PbmVEcml2ZSAtIE5leHVzMzY1L0ludGVyb1N0dWR5MjAyMC9hbmFseXNpcy9EYXRhQW5hbHlzaXNKYW51YXJ5MjAyMC9EYXRhQW5hbHlzaXNKYW4yMDIwL3RtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjEucmRzIikKCgojIG1lcmdlIHdpdGggYmVoYXZpb3VyYWwgZGF0YQp1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRzc2lkKQpjb2xuYW1lcyhkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0KQpjb2xuYW1lcyh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxKQoKZGJfZnVsbDRuZXdfc3RpbQpjb2xuYW1lcyhkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0KQpkYl9mdWxsNG5ld19zdGltX3N1YnNldDwtIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RbLGMoMTo0LDY6NywxMjoxMywxNiwyMToyNywgMzE6NTYsODA6ODEsODQ6OTYsOTg6MTE0LDExNjoxMjQpXQoKCiMgbWF0Y2ggdHlwZXMgb2YgbWVyZ2luZyB2YXJpYWJsZXMKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIkc3NpZDwtIGFzLmNoYXJhY3Rlcih0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoMiRzc2lkKQoKZGJfZnVsbDRuZXdfc3RpbV9zdWJzZXQkc3NpZDwtIGFzLmNoYXJhY3RlcihkYl9mdWxsNG5ld19zdGltX3N1YnNldCRzc2lkKQoKIyB0Tm8KCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyJHRObyA8LSBhcy5jaGFyYWN0ZXIodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIkdE5vKQpkYl9mdWxsNG5ld19zdGltX3N1YnNldCR0Tm8gPC0gYXMuY2hhcmFjdGVyKGRiX2Z1bGw0bmV3X3N0aW1fc3Vic2V0JHRObykKdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc3Vic2V0JHRObykKdW5pcXVlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyJHRObykKIyBtZXJnZQpucm93KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyKQojIDE3MjE2OAojIDg3NTI5Cgp0YWJsZShpcy5uYShkYl9mdWxsNG5ld19zdGltX3N1YnNldCRtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIkdE5vPC0gYXMubnVtZXJpYyh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoMiR0Tm8pCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIlPiUKICBhcnJhbmdlKHNzaWQsdE5vLCB0aW1lcmV6ZXJvMykKCgpkYl9mdWxsNG5ld19zdGltX3N1YnNldCR0CnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWg8LSBsZWZ0X2pvaW4odG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIsIGRiX2Z1bGw0bmV3X3N0aW1fc3Vic2V0KQoKCnVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3N1YnNldCRzdGltSUFQUykKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyJHRyaWFsVW5xCgp1bmlxdWUodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaDIkc3NpZCkKdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc3Vic2V0JHNzaWQpCgoKZGJfZnVsbDRuZXdfc3RpbV9zdWJzZXQkdE5vPC0gYXMubnVtZXJpYyhkYl9mdWxsNG5ld19zdGltX3N1YnNldCR0Tm8pCgoKdGFibGUoaXMubmEoZGJfZnVsbDRuZXdfc3RpbV9zdWJzZXQkYXJvdXNhbCkpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3PC0gcmlnaHRfam9pbih0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoMiwgZGJfZnVsbDRuZXdfc3RpbV9zdWJzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdzc2lkJywgJ3RObycpKQoKbnJvdyh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoKQojIDE3MjE2OCBnb29kCgpucm93KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyKQoKbnJvdyh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3KQo4NzUyOQoKdGFibGUoaXMubmEodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpKQoKc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsIGlzLm5hKGFyb3VzYWwpKQoKdW5pcXVlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgyJHRyaWFsVW5xKQoKYGBgCgoKYGBge3J9CiMgY2hlY2sKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKGdyb3VuZF9hcm91c2FsX2xhYikpJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZXJlemVybzMsIHkgPSBwdXBfYmFzQ29yKSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPSBncm91bmRfYXJvdXNhbF9sYWIsIGNvbG9yID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSwgZnVuID0gbWVhbixnZW9tID0gImxpbmUiLAogICAgICAgICAgICAgICBzZSA9IEYsIGFscGhhID0gLjEsIHNpemUgPSAxLjUpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD1ncm91bmRfYXJvdXNhbF9sYWIsIGNvbG9yID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSwgc2l6ZSA9IDMpKyAgCnRoZW1lX2NsYXNzaWMoKSsKICB5bGFiKCJQdXBpbCBzaXplICh6KSIpKwogIHhsYWIoIlRpbWUgKHMpIikrCiAgIyBwJGdyYXBoc3R5bGUrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICB4bGltKDAsNikrCiAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSkKCgoKCgoKYGBgCgpwdXBpbCB0aW1lY291cnNlCgpgYGB7cn0KCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWggJT4lCiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpKSU+JQogIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSklPiUKICBnZ3Bsb3QoYWVzKHggPSB0aW1lcmV6ZXJvMywgeSA9IHB1cF9iYXNDb3IpKSsKICBzdGF0X3Ntb290aChhZXMoZ3JvdXA9IG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiwgY29sb3IgPSBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpLCBmdW4gPSBtZWFuLGdlb20gPSAibGluZSIsCiAgICAgICAgICAgICAgIHNlID0gRiwgYWxwaGEgPSAuMSwgc2l6ZSA9IDEuNSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPW1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiwgY29sb3IgPSBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpLCBzaXplID0gMykrICAKdGhlbWVfY2xhc3NpYygpKwogIHlsYWIoIlB1cGlsIHNpemUgKHopIikrCiAgeGxhYigiVGltZSAocykiKSsKICAjIHAkZ3JhcGhzdHlsZSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIHhsaW0oMCw2KSsKICAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKQoKCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoICU+JQogIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSU+JQogIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSU+JQogIGdncGxvdChhZXMoeCA9IHRpbWVyZXplcm8zLCB5ID0gcHVwX2Jhc0NvcikpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD0gbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwsIGNvbG9yID0gbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwpLCBmdW4gPSBtZWFuLGdlb20gPSAibGluZSIsCiAgICAgICAgICAgICAgIHNlID0gRiwgYWxwaGEgPSAuMSwgc2l6ZSA9IDEuNSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPW1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsLCBjb2xvciA9IG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsKSwgc2l6ZSA9IDMpKyAgCnRoZW1lX2NsYXNzaWMoKSsKICB5bGFiKCJQdXBpbCBzaXplICh6KSIpKwogIHhsYWIoIlRpbWUgKHMpIikrCiAgIyBwJGdyYXBoc3R5bGUrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICB4bGltKDAsNikrCiAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKQoKYGBgCgoKdW5pcXVlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkY29uZGl0aW9uKQoKYGBge3J9CnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkdmFsZW5jZWFyb3VzYWxfb3V0bGllcnM8LSBpZl9lbHNlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkQXJvdXNhbE1lYW48IDYuNyAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgPT0gIk1vcmUgbmVnYXRpdmUiLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmX2Vsc2UodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCRBcm91c2FsTWVhbj4gMi45NCAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgPT0gIk1vcmUgcG9zaXRpdmUiLCBUUlVFLCBGQUxTRSkpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICAjIHN1YnNldCh2YWxlbmNlYXJvdXNhbF9vdXRsaWVycyA9PSBUUlVFKSAlPiUKICBncm91cF9ieShzdGltSUFQUyxtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIEFyb3VzYWxNZWFuKSkrCiAgIyBnZW9tX2JveHBsb3QoKSsKICAjIGdlb21fcG9pbnQoKSsKICAjIGdlb21fdGV4dChhZXMobGFiZWwgPSBzdGltSUFQUykpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjIpKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNi43KSsKICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMi45NCkKCgogIAoKIyB0aGlzbXBsb3QgcmFpc2VzIHF1ZXN0aW9uIHJlZ2FyZGluZyB3dGh0ZWhyIHRoZSBiZXR0ZXIgY29ycmVsYXRpb24gYnd0ZWVuIHN1YmplY3RpdmUgYW5kIG9iamVjdGl2ZSBhcm91c2FsIGZvciBwb3NpdGl2ZSBzdG9tdWxpIHJlZmxlY3RzIHRoZSBmYWN0IHRoYXQgZm9yIG5lZ2F0aXZlIHdlIGRvbid0IGhhdmUgbWFueSBsb3cgYXJvdXNhbCBvbmVzLiBCdXQgdGhpcyBpcyB1bmxpa2VsbHkgYmVjYXVzZSB0aGUgb3Bvc2l0ZSB1cyBhbHNvIHRydWUgZm9yIHBvc2l0dWl2ZSBzdGltdWxpLCBub3RtYW55IHBvc2l0aXZlIHN0b211bGkgYXJlIHJhdGVkIGFzIGhpZ2hseSBhcm91c2luZyBpbiBzZWtmIHJlcG9ydCwgc28gd2Ugd291bGQgbm90IGV4cGVjdAoKCiMgbGVzcyByZXN0cnVjdCB2YXJvYWJpbGl0eQp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoICU+JQogIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSklPiUKICBzdWJzZXQodmFsZW5jZWFyb3VzYWxfb3V0bGllcnMgPT0gVFJVRSkgJT4lCiAgIyBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZXJlemVybzMsIHkgPSBwdXBfYmFzQ29yKSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPSBtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSwgZnVuID0gbWVhbixnZW9tID0gImxpbmUiLAogICAgICAgICAgICAgICBzZSA9IEYsIGFscGhhID0gLjEsIHNpemUgPSAxLjUpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD1tZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSwgc2l6ZSA9IDMpKyAgCnRoZW1lX2NsYXNzaWMoKSsKICB5bGFiKCJQdXBpbCBzaXplICh6KSIpKwogIHhsYWIoIlRpbWUgKHMpIikrCiAgIyBwJGdyYXBoc3R5bGUrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICB4bGltKDAsNikrCiAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikKICAgICAgICAgICAgICAKICAgICAgICAgICAgICAKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgc3Vic2V0KHZhbGVuY2Vhcm91c2FsX291dGxpZXJzID09IFRSVUUpICU+JQogICMgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpKSU+JQogIGdncGxvdChhZXMoeCA9IHRpbWVyZXplcm8zLCB5ID0gcHVwX2Jhc0NvcikpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD0gbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBjb2xvciA9IG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiksIGZ1biA9IG1lYW4sZ2VvbSA9ICJsaW5lIiwKICAgICAgICAgICAgICAgc2UgPSBGLCBhbHBoYSA9IC4xLCBzaXplID0gMS41KSsKICBzdGF0X3Ntb290aChhZXMoZ3JvdXA9bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBjb2xvciA9IG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiksIHNpemUgPSAzKSsgIAp0aGVtZV9jbGFzc2ljKCkrCiAgeWxhYigiUHVwaWwgc2l6ZSAoeikiKSsKICB4bGFiKCJUaW1lIChzKSIpKwogICMgcCRncmFwaHN0eWxlKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgeGxpbSgwLDYpKwogICBmYWNldF9ncmlkKG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMn4uKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKQoKCgpgYGAKCgp1bmlxdWUodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCR0aW1lYmluMikKIyAzMCB0aW1lIGJpbnMKCmBgYHtyfQojIHB2YWw8LSBjb3IudGVzdCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJHNkZXZnYXplX3BhcnNlZCwgdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCRwdXBfYmFzQ29yKQojIHB2YWwkZXN0aW1hdGUKCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJHNzaWRfbnVtPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCRzc2lkKSkKCmxpYnJhcnkocHVycnIpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3PC10bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JT4lCnVuZ3JvdXAoKSU+JQogIG11dGF0ZShtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIgPSAKICAgICAgICAgICBpZl9lbHNlKFZhbGVuY2VNZWFuVGhpc1NhbXBsZSA+PSAKICAgICAgICAgICAgICAgICAgICAgbWVkaWFuKFZhbGVuY2VNZWFuVGhpc1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgIk1vcmUgcG9zaXRpdmUiLCAiTW9yZSBuZWdhdGl2ZSIpKSU+JQogIG11dGF0ZShtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIgPSBpZl9lbHNlKEFyb3VzYWxNZWFuVGhpc1NhbXBsZSA+PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbihBcm91c2FsTWVhblRoaXNTYW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtID0gVFJVRSksICJIaWdoIiwgIkxvdyIpKQoKCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHNzaWRfc3BsaXRfdmFsX3RpbWU8LSBwYXN0ZTAodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRzc2lkLCAgICAgICAgICAKcGFzdGUwKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLAogICAgICAgcGFzdGUwKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZWJpbjIpKSkKCgp0YWJsZShpcy5uYSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSkpCnVuaXF1ZSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJHNzaWRfc3BsaXRfdmFsX3RpbWUpCnN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoLCBpcy5uYShtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRzc2lkX251bTwtIGFzLm51bWVyaWModG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRzc2lkKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyA8LSB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAjIHN1YnNldChzc2lkID09IDMyMCklPiUKICB1bmdyb3VwKCklPiUKICBncm91cF9ieShzc2lkX3NwbGl0X3ZhbF90aW1lKSU+JQogIG11dGF0ZShjb3JfYXJvdXNfcHVwID0gY29yLnRlc3QocHVwX2Jhc0NvciwgYXJvdXNhbF9jLCB1c2UgPSAiY29tcGxldGUiKSRlc3RpbWF0ZSwKICAgICAgICAgY29yX2Fyb3VzX3B1cF9wdmFsID0gY29yLnRlc3QocHVwX2Jhc0NvciwgYXJvdXNhbF9jLCB1c2UgPSAiY29tcGxldGUiKSRwLnZhbHVlKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldzwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXclPiUKICBncm91cF9ieSh0aW1lYmluMiklPiUKICBtdXRhdGUobWVhbl9jb3JfcHVwID0gbWVhbihjb3JfYXJvdXNfcHVwLCBuYS5ybSA9IFRSVUUpLCBzZF9jb3JfcHVwID0gc2QoY29yX2Fyb3VzX3B1cCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgbWVhbl9jb3JfcHVwX3B2YSA9IG1lYW4oY29yX2Fyb3VzX3B1cF9wdmFsLCBuYS5ybSA9IFRSVUUpLCBzZF9jb3JfYXJvdXNfcHVwX3B2YWwgPSBzZChjb3JfYXJvdXNfcHVwX3B2YWwsIG5hLnJtID0gVFJVRSkpCiAgCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHB2YWxfc2lnbjwtIGlmX2Vsc2UodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRtZWFuX2Nvcl9wdXBfcHZhIDwgLjA1LCB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JG1lYW5fY29yX3B1cF9wdmEsIE5VTEwpCgoKCnR0ZXN0Y2hlY2s8LSB0LnRlc3QodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRjb3JfYXJvdXNfcHVwKQp0dGVzdGNoZWNrJHAudmFsdWUKdHRlc3RjaGVjayRwYXJhbWV0ZXIKCnVuaXF1ZSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHNzaWRfc3BsaXRfdmFsX3RpbWUpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHZhbGVfdGltZWJpbjwtIHBhc3RlMCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiwgcGFzdGUwKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZWJpbjIpKQoKIyBzdWJzZXQodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywgdmFsZV90aW1lYmluID09ICJNb3JlIG5lZ2F0aXZlKDIuNiwyLjgyXSIpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHNzaWQ8LSBhcy5jaGFyYWN0ZXIodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRzc2lkKQoKCgoKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcgJT4lCiAgICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsIHRpbWViaW4yKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ3JvdXBfYnkobWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLHRpbWViaW4yKSU+JQogIG11dGF0ZShwdmFsID0gdC50ZXN0KGNvcl9hcm91c19wdXApJHAudmFsdWUsIGRmID0gdC50ZXN0KGNvcl9hcm91c19wdXApJHBhcmFtZXRlciklPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsdGltZWJpbjIpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKHRpbWVyZXplcm8zLCBjb3JfYXJvdXNfcHVwLCBjb2xvciA9IG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikpKwogICMgZ2VvbV9zCiAgc3RhdF9zdW1tYXJ5KGZ1biA9IG1lYW4sIGdlb20gPSAnbGluZScsIHNpemUgPSA0KSsKICAjIHN0YXRfc3VtbWFyeShhZXMoeSA9IHB2YWwpLCBmdW4gPSBtZWFuLCBnZW9tID0gJ2xpbmUnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IC4yKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAuMDUsIGxpbmV0eXBlID0gImRhc2hlZCIpKwogIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4xLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSsKICB0aGVtZV9jbGFzc2ljKCkKCgpucm93KGxlZnRfam9pbih0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LCBmbGFnX3Bvc19uZWcpKQpucm93KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRjb3JfcG9zX25lZ19kaWZmX2xhYjwtIE5VTEwKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRjb3JfcG9zX25lZ19kaWZmPC1OVUxMCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXc8LSBsZWZ0X2pvaW4odG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywgZmxhZ19wb3NfbmVnKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyAlPiUKICBzdWJzZXQoIWlzLm5hKGNvcl9wb3NfbmVnX2RpZmZfbGFiKSklPiUKICAjIHN1YnNldChjb3JfcG9zX25lZ19kaWZmX2xhYiA9PSAicG9zID4gbmVnIikgJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLCB0aW1lYmluMixjb3JfcG9zX25lZ19kaWZmX2xhYikgJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsdGltZWJpbjIpICU+JQogIG11dGF0ZShwdmFsID0gdC50ZXN0KGNvcl9hcm91c19wdXApJHAudmFsdWUsIGRmID0gdC50ZXN0KGNvcl9hcm91c19wdXApJHBhcmFtZXRlciklPiUKICBncm91cF9ieShtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsdGltZWJpbjIsY29yX3Bvc19uZWdfZGlmZl9sYWIpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSkgJT4lCiAgIyBnZ3Bsb3QoYWVzKHRpbWVyZXplcm8zLCBjb3JfYXJvdXNfcHVwLCBjb2xvciA9IG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikpKwogIGdncGxvdChhZXModGltZXJlemVybzMsIGNvcl9hcm91c19wdXAsIGNvbG9yID0gIGNvcl9wb3NfbmVnX2RpZmZfbGFiKSkrCiAgIyBnZW9tX3MKICBzdGF0X3N1bW1hcnkoZnVuID0gbWVhbiwgZ2VvbSA9ICdsaW5lJywgc2l6ZSA9IDQpKwogICMgc3RhdF9zdW1tYXJ5KGFlcyh5ID0gcHZhbCksIGZ1biA9IG1lYW4sIGdlb20gPSAnbGluZScsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gLjIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4wNSwgbGluZXR5cGUgPSAiZGFzaGVkIikrCiAgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjEsIGxpbmV0eXBlID0gImRvdHRlZCIpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGxpbmV0eXBlID0gImRvdHRlZCIpKwogICMgZ2VvbV9yZWN0KHhtaW4gPSAuNSwgeG1heCA9IDEsIHltaW4gPSAtLjIsIHltYXggPSAxLCBhbHBoYSA9IC4wMSwgY29sb3IgPSBGQUxTRSkrCiAgdGhlbWVfY2xhc3NpYygpKwogICAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKQoKCgpyYW5nZSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHB2YWxfc2lnbiwgbmEucm0gPSBUUlVFKQp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHNzaWRfc3BsaXRfdmFsX3RpbWUKCgoKCgojIGxldCdzIGlkZW50aWZ5IHRoZSBwZW9wbGUgd2hpbyBzaG93IHRoZSBuZWdhdGl2ZSBhcm91c2FsIGVmZmVjdAoKYGBgCgp0aW1lY291cnNlIGFuYWx5c3MgdXNpbmcgbG1lcgoKMS0gc2VsZWN0IGEgYmluCjIgLSBmaXQgYSBsbWVyCjMgLSBzYXZlIHN0YXRpc3RpY3MgKGVzdGltYXRlIGFuZCBwIHZhbHVlKQozIC0gY3JlYXRlIGNsdXN0ZXJzIChwIHZhbHVlIDwgLjA1IGluIGF0IGxlYXN0IDMgY29uc2VjdXRpdmUgYmlucykKCmBgYHtyfQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyQKaSA9IDEKCm5iaW5zPC0gdW5pcXVlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZWJpbjIpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3Cgp1bmlxdWUodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lYmluMikKbG1lcl9iaW5fcHVwPC0gbGlzdCgpIAoKIyA8LSBucm93KG5iaW5zKQoKCm5iaW5zPC0gdW5pcXVlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZWJpbjIpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRMYWJlbDwtIHN1YnN0cih0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHN0aW1JQVBTLCAxLDgpCgppbWFnZUpfSUFQUyRMYWJlbApucm93KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcpCiMgNjI5MjEKbnJvdyhsZWZ0X2pvaW4odG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywgaW1hZ2VKX0lBUFMpKQoKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXc8LSBsZWZ0X2pvaW4odG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywgaW1hZ2VKX0lBUFMpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRNZWFuX2dyYXlfejwtIHNjYWxlKHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckTWVhbiwgc2NhbGUgPSBUUlVFLCBjZW50ZXIgPSBUUlVFKVssMV0KCgp0ZXN0PC0gbG1lcihwdXBfYmFzQ29yIH4gYXJvdXNhbF9jK01lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWViaW4yID09IG5iaW5zW2JdKSkKCnN1bW1hcnkodGVzdCkKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdE5vCiIoMC4wNDExLDAuMjYxXSIKc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWViaW4yID09IG5iaW5zWzI4XSAmIHNzaWQgPT0gMzQxICYgdE5vID09IDMpCgp0ZXN0CnJtKGkpCgppID0gMSAjIHJlbWVtYmVyIHRvIGFsd2F5cyByZXplcm8gaXQKIyBiID0gMzQKbmJpbnM8LSBuYmluc1sxOjI4XQp1bmlxdWUobmJpbnMpCgojIG5iaW5zPC0gYXMKCiMgcG9zaXRpdmUKCiMgY3JlYXRlIG51bWJlciBzIGZvciB0aW1lIGJpbnMKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldzwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXclPiUKICBncm91cF9ieShzc2lkLCBzdGltSUFQUyklPiUKICBtdXRhdGUodGltZWJpbl9ubyA9IDE6bigpKQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyU+JQogICMgZ3JvdXBfYnkoc3NpZCwgc3RpbUlBUFMpCiAgZ2dwbG90KGFlcyh0aW1lYmluX25vKSkrCiAgZ2VvbV9oaXN0b2dyYW0oKSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyOCkrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwKQoKYGBgCgoKYGBge3J9CgoKbnJvdyhuYmlucykKbmJpbnMgPSAzMAp0aW1lY291cnNlX3Jlc3VsdF9kZiA8LSBkYXRhLmZyYW1lKHRpbWViaW5zPSByZXAoTkEsIDMwKSwgRXN0aW1hdGU9IHJlcChOQSwgMzApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0PXJlcChOQSwgMzApLCBwPXJlcChOQSwgMzApLCBjb3Y9IGFzLmNoYXJhY3RlcihyZXAoTkEsMzApKSkKClZpZXcodGltZWNvdXJzZV9yZXN1bHRfZGYpCgpuYmluczwtIG5iaW5zWzE6MjhdCgoKCmkgPSAxICMgcmVtZW1iZXIgdG8gYWx3YXlzIHJlemVybyBpdAojIGIgPSAzNAoKbmJpbnM8LSB1bmlxdWUodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lYmluX25vKQoKdW5pcXVlKG5iaW5zKQpmb3IgKGIgaW4gMTpsZW5ndGgobmJpbnMpKSB7CiAgIyBmb3IgKHMgaW4gMTpsZW5ndGgobnNpbSkpIHsKCiAgICBtZXNzYWdlKHNwcmludGYoIiQkJCQkUlVOSU5HIGxtZXIgJWkiLCBuYmluc1tiXSkpCiAgICAjIGRiX29mN19uZXdfSkVGRkUkVmlkZW9UeXBlX2NvbnRyYXN0X3NhbXBsZTwtIHNhbXBsZSgocmVwKGMoLS41LCAuNSksIGVhY2ggPSAgMTkyMCkpLCByZXBsYWNlID0gRkFMU0UpIAogICAgICAgICNydW4gdGhlIG1vZGVsIG9uIHRoZSBjdXJyZW50IHRpbWUgYmluIGFuZCBzaW11bGF0aW9uIHN1bWJlcgogICAgICAgIGxtZXJfYmluX3B1cCAgPC0gbG1lcihwdXBfYmFzQ29yIH4gYXJvdXNhbF9jK01lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UgPT0gIk1vcmUgcG9zaXRpdmUiICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWViaW5fbm8gPT0gbmJpbnNbYl0pKQoKICAgICAgICAjc3RvcmUgcmVzdWx0cyBmcm9tIHRoZSBzaW11bGF0aW9uCiAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5PC0gc3VtbWFyeShsbWVyX2Jpbl9wdXApCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmW2ksMV08LSB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHRpbWVyZXplcm8zW2JdICNzYXZlIHRoZSBleGFjdCB2YWx1ZSBvZiB0aW1lIGJpbgogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZltpLDJdPC0gbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiwxXSAjIHMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZbaSwzXTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw0XSAjIHQgc3RhdGlzdGljCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmW2ksNF08LWxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsNV0gIyBwIHZhbHVlCiAgICAgICAgICAgICMgc2ltdWxhdGVkX2NsdXN0ZXJzX0pFRkZFW2ksNl08LSBuc2ltW3NdICNzdG9yZSBzaW11bGF0aW9uIG91bnQKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZbaSw1XSA8LWlmZWxzZShsZW5ndGgobG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlLCAncGFzcycpCgogICAgIGkgPSBpKzEKfQoKCiMgdGltZWNvdXJzZV9yZXN1bHRfZGZfcG9zPC0gdGltZWNvdXJzZV9yZXN1bHRfZGYKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmJT4lCiAgZ2dwbG90KGFlcyh0aW1lYmlucywgdCkpKwogIGdlb21fbGluZShzaXplID0gMikrCiAgZ2VvbV9saW5lKGFlcyh5ID0gcCksIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAyKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAuMDUsIGNvbG9yID0gJ3JlZCcsIHNpemUgPSAxLjUpCgoKYGBgCgoKIyBuZWdhdGl2ZSBsbWVyCmBgYHtyfQoKdGltZWNvdXJzZV9yZXN1bHRfZGZfbmVnIDwtIGRhdGEuZnJhbWUodGltZWJpbnM9IHJlcChOQSwgMzApLCBFc3RpbWF0ZT0gcmVwKE5BLCAzMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQ9cmVwKE5BLCAzMCksIHA9cmVwKE5BLCAzMCksIGNvdj0gYXMuY2hhcmFjdGVyKHJlcChOQSwzMCkpKQoKCmkgPSAxCgpmb3IgKGIgaW4gMTpsZW5ndGgobmJpbnMpKSB7CiAgIyBmb3IgKHMgaW4gMTpsZW5ndGgobnNpbSkpIHsKCiAgICBtZXNzYWdlKHNwcmludGYoIiQkJCQkUlVOSU5HIGxtZXIgJWkiLCBuYmluc1tiXSkpCiAgICAjIGRiX29mN19uZXdfSkVGRkUkVmlkZW9UeXBlX2NvbnRyYXN0X3NhbXBsZTwtIHNhbXBsZSgocmVwKGMoLS41LCAuNSksIGVhY2ggPSAgMTkyMCkpLCByZXBsYWNlID0gRkFMU0UpIAogICAgICAgICNydW4gdGhlIG1vZGVsIG9uIHRoZSBjdXJyZW50IHRpbWUgYmluIGFuZCBzaW11bGF0aW9uIHN1bWJlcgogICAgICAgIGxtZXJfYmluX3B1cCAgPC0gbG1lcihwdXBfYmFzQ29yIH4gYXJvdXNhbF9jK01lYW5fZ3JheV96ICArKDEgK01lYW5fZ3JheV96IHwgc3NpZCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSA9PSAiTW9yZSBuZWdhdGl2ZSIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWJpbl9ubyA9PSBuYmluc1tiXSkpCgogICAgICAgICNzdG9yZSByZXN1bHRzIGZyb20gdGhlIHNpbXVsYXRpb24KICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnk8LSBzdW1tYXJ5KGxtZXJfYmluX3B1cCkKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfbmVnW2ksMV08LSB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHRpbWVyZXplcm8zW2JdICNzYXZlIHRoZSBleGFjdCB2YWx1ZSBvZiB0aW1lIGJpbgogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl9uZWdbaSwyXTwtIGxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsMV0gIyBzCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX25lZ1tpLDNdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDRdICMgdCBzdGF0aXN0aWMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfbmVnW2ksNF08LWxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsNV0gIyBwIHZhbHVlCiAgICAgICAgICAgICMgc2ltdWxhdGVkX2NsdXN0ZXJzX0pFRkZFW2ksNl08LSBuc2ltW3NdICNzdG9yZSBzaW11bGF0aW9uIG91bnQKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfbmVnW2ksNV0gPC1pZmVsc2UobGVuZ3RoKGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICE9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSwgJ3Bhc3MnKQoKICAgICBpID0gaSsxCn0KCgpWaWV3KHRpbWVjb3Vyc2VfcmVzdWx0X2RmX25lZykKCiMgd2hldGhlciBJIHVzZSBncm91bmQgdmFsZW5jZSwgc2VsZiB2YWxlbWNlIG9yIHRoaXMgc2FtcGxlIGF2ZXJhZ2UgdmFsZW5jZSwgSSBnZXQgdGhlIHNhbWUgcGF0dGVybnMKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX25lZyU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjEsIGNvbG9yID0gJ3JlZCcsIHNpemUgPSAxLjUpCgpgYGAKCgoKYGBge3J9CnRpbWVjb3Vyc2VfcmVzdWx0X2RmJFZhbGVuY2UgPC0gIk1vcmUgbmVnYXRpdmUiCgp0aW1lY291cnNlX3Jlc3VsdF9kZl9uZWckVmFsZW5jZTwtICJNb3JlIHBvc2l0aXZlIgoKYmluZF9yb3dzKHRpbWVjb3Vyc2VfcmVzdWx0X2RmLHRpbWVjb3Vyc2VfcmVzdWx0X2RmX25lZyklPiUKICAgIGdncGxvdChhZXModGltZWJpbnMsIHQsIGNvbG9yID0gVmFsZW5jZSkpKwogIGdlb21fbGluZShzaXplID0gMikrCiAgZ2VvbV9saW5lKGFlcyh5ID0gcCksIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAyKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAuMDUsIGNvbG9yID0gJ3JlZCcsIHNpemUgPSAxLjUpCgoKYGBgCiMgdXNlIHZhbGVuY2UgdG8gcHVwaWwKYGBge3J9CnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbCA8LSBkYXRhLmZyYW1lKHRpbWViaW5zPSByZXAoTkEsIDMwKSwgRXN0aW1hdGU9IHJlcChOQSwgMzApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0PXJlcChOQSwgMzApLCBwPXJlcChOQSwgMzApLCBjb3Y9IGFzLmNoYXJhY3RlcihyZXAoTkEsMzApKSkKCgppID0gMQoKZm9yIChiIGluIDE6bGVuZ3RoKG5iaW5zKSkgewogICMgZm9yIChzIGluIDE6bGVuZ3RoKG5zaW0pKSB7CgogICAgbWVzc2FnZShzcHJpbnRmKCIkJCQkJFJVTklORyBsbWVyICVpIiwgbmJpbnNbYl0pKQogICAgIyBkYl9vZjdfbmV3X0pFRkZFJFZpZGVvVHlwZV9jb250cmFzdF9zYW1wbGU8LSBzYW1wbGUoKHJlcChjKC0uNSwgLjUpLCBlYWNoID0gIDE5MjApKSwgcmVwbGFjZSA9IEZBTFNFKSAKICAgICAgICAjcnVuIHRoZSBtb2RlbCBvbiB0aGUgY3VycmVudCB0aW1lIGJpbiBhbmQgc2ltdWxhdGlvbiBzdW1iZXIKICAgICAgICBsbWVyX2Jpbl9wdXAgIDwtIGxtZXIocHVwX2Jhc0NvciB+IGFyb3VzYWxfYysgdmFsZW5jZV9jKyBNZWFuX2dyYXlfeiAgKygxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlID09ICJNb3JlIG5lZ2F0aXZlIiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lYmluX25vID09IG5iaW5zW2JdKSkKCiAgICAgICAgI3N0b3JlIHJlc3VsdHMgZnJvbSB0aGUgc2ltdWxhdGlvbgogICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeTwtIHN1bW1hcnkobG1lcl9iaW5fcHVwKQogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxbaSwxXTwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZXJlemVybzNbYl0gI3NhdmUgdGhlIGV4YWN0IHZhbHVlIG9mIHRpbWUgYmluCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbFtpLDJdPC0gbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiwxXSAjIHMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsW2ksM108LWxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsNF0gIyB0IHN0YXRpc3RpYwogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxbaSw0XTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw1XSAjIHAgdmFsdWUKICAgICAgICAgICAgIyBzaW11bGF0ZWRfY2x1c3RlcnNfSkVGRkVbaSw2XTwtIG5zaW1bc10gI3N0b3JlIHNpbXVsYXRpb24gb3VudAogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxbaSw1XSA8LWlmZWxzZShsZW5ndGgobG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlLCAncGFzcycpCgogICAgIGkgPSBpKzEKfQoKIyB2YWxlbmNlIHRvIHB1cGlsCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbCU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjA1LCBjb2xvciA9ICdyZWQnLCBzaXplID0gMS41KQoKYGBgCgoKIyB1c2UgdmFsZW5jZSB0byBwdXBpbAoKYGBge3J9CnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXIgPC0gZGF0YS5mcmFtZSh0aW1lYmlucz0gcmVwKE5BLCAzMCksIEVzdGltYXRlPSByZXAoTkEsIDMwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdD1yZXAoTkEsIDMwKSwgcD1yZXAoTkEsIDMwKSwgY292PSBhcy5jaGFyYWN0ZXIocmVwKE5BLDMwKSkpCgoKaSA9IDEKCmZvciAoYiBpbiAxOmxlbmd0aChuYmlucykpIHsKICAjIGZvciAocyBpbiAxOmxlbmd0aChuc2ltKSkgewoKICAgIG1lc3NhZ2Uoc3ByaW50ZigiJCQkJCRSVU5JTkcgbG1lciAlaSIsIG5iaW5zW2JdKSkKICAgICMgZGJfb2Y3X25ld19KRUZGRSRWaWRlb1R5cGVfY29udHJhc3Rfc2FtcGxlPC0gc2FtcGxlKChyZXAoYygtLjUsIC41KSwgZWFjaCA9ICAxOTIwKSksIHJlcGxhY2UgPSBGQUxTRSkgCiAgICAgICAgI3J1biB0aGUgbW9kZWwgb24gdGhlIGN1cnJlbnQgdGltZSBiaW4gYW5kIHNpbXVsYXRpb24gc3VtYmVyCiAgICAgICAgbG1lcl9iaW5fcHVwICA8LSBsbWVyKHB1cF9iYXNDb3IgfiB2YWxlbmNlX2MrIGFyb3VzYWwrTWVhbl9ncmF5X3ogICsoMSArIE1lYW5fZ3JheV96IHwgc3NpZCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSA9PSAiTW9yZSBuZWdhdGl2ZSIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWJpbl9ubyA9PSBuYmluc1tiXSkpCgogICAgICAgICNzdG9yZSByZXN1bHRzIGZyb20gdGhlIHNpbXVsYXRpb24KICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnk8LSBzdW1tYXJ5KGxtZXJfYmluX3B1cCkKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcltpLDFdPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lcmV6ZXJvM1tiXSAjc2F2ZSB0aGUgZXhhY3QgdmFsdWUgb2YgdGltZSBiaW4KICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcltpLDJdPC0gbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiwxXSAjIHMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcltpLDNdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDRdICMgdCBzdGF0aXN0aWMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcltpLDRdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDVdICMgcCB2YWx1ZQogICAgICAgICAgICAjIHNpbXVsYXRlZF9jbHVzdGVyc19KRUZGRVtpLDZdPC0gbnNpbVtzXSAjc3RvcmUgc2ltdWxhdGlvbiBvdW50CiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXJbaSw1XSA8LWlmZWxzZShsZW5ndGgobG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlLCAncGFzcycpCgogICAgIGkgPSBpKzEKfQoKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXIlPiUKICBnZ3Bsb3QoYWVzKHRpbWViaW5zLCB0KSkrCiAgZ2VvbV9saW5lKHNpemUgPSAyKSsKICBnZW9tX2xpbmUoYWVzKHkgPSBwKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4wNSwgY29sb3IgPSAncmVkJywgc2l6ZSA9IDEuNSkKCgoKYGBgCgp2YWxlbmNlIGZvciBoaWdoIHZzIGxvdwpgYGB7cn0KdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9uZWcgPC0gZGF0YS5mcmFtZSh0aW1lYmlucz0gcmVwKE5BLCAzMCksIEVzdGltYXRlPSByZXAoTkEsIDMwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdD1yZXAoTkEsIDMwKSwgcD1yZXAoTkEsIDMwKSwgY292PSBhcy5jaGFyYWN0ZXIocmVwKE5BLDMwKSkpCgoKaSA9IDEKCmZvciAoYiBpbiAxOmxlbmd0aChuYmlucykpIHsKICAjIGZvciAocyBpbiAxOmxlbmd0aChuc2ltKSkgewoKICAgIG1lc3NhZ2Uoc3ByaW50ZigiJCQkJCRSVU5JTkcgbG1lciAlaSIsIG5iaW5zW2JdKSkKICAgICMgZGJfb2Y3X25ld19KRUZGRSRWaWRlb1R5cGVfY29udHJhc3Rfc2FtcGxlPC0gc2FtcGxlKChyZXAoYygtLjUsIC41KSwgZWFjaCA9ICAxOTIwKSksIHJlcGxhY2UgPSBGQUxTRSkgCiAgICAgICAgI3J1biB0aGUgbW9kZWwgb24gdGhlIGN1cnJlbnQgdGltZSBiaW4gYW5kIHNpbXVsYXRpb24gc3VtYmVyCiAgICAgICAgbG1lcl9iaW5fcHVwICA8LSBsbWVyKHB1cF9iYXNDb3IgfiB2YWxlbmNlX2MgKyBNZWFuX2dyYXlfeiAgKygxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiA9PSAiSGlnaCIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lYmluX25vID09IG5iaW5zW2JdKSkKCiAgICAgICAgI3N0b3JlIHJlc3VsdHMgZnJvbSB0aGUgc2ltdWxhdGlvbgogICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeTwtIHN1bW1hcnkobG1lcl9iaW5fcHVwKQogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxfYW5kX2FyX25lZ1tpLDFdPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lcmV6ZXJvM1tiXSAjc2F2ZSB0aGUgZXhhY3QgdmFsdWUgb2YgdGltZSBiaW4KICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9uZWdbaSwyXTwtIGxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsMV0gIyBzCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXJfbmVnW2ksM108LWxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsNF0gIyB0IHN0YXRpc3RpYwogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxfYW5kX2FyX25lZ1tpLDRdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDVdICMgcCB2YWx1ZQogICAgICAgICAgICAjIHNpbXVsYXRlZF9jbHVzdGVyc19KRUZGRVtpLDZdPC0gbnNpbVtzXSAjc3RvcmUgc2ltdWxhdGlvbiBvdW50CiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXJfbmVnW2ksNV0gPC1pZmVsc2UobGVuZ3RoKGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICE9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSwgJ3Bhc3MnKQoKICAgICBpID0gaSsxCn0KClZpZXcodGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9uZWcpCgp0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxfYW5kX2FyX25lZyU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjA1LCBjb2xvciA9ICdyZWQnLCBzaXplID0gMS41KSsKICBnZ3RpdGxlKCJwdXBpbCB+IHZhbGVuY2UgZm9yIGhpZ2ggYXJvdXNhbCIpCgpgYGAKCiMgCgpgYGB7cn0KdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9sb3cgPC0gZGF0YS5mcmFtZSh0aW1lYmlucz0gcmVwKE5BLCAzMCksIEVzdGltYXRlPSByZXAoTkEsIDMwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdD1yZXAoTkEsIDMwKSwgcD1yZXAoTkEsIDMwKSwgY292PSBhcy5jaGFyYWN0ZXIocmVwKE5BLDMwKSkpCgoKaSA9IDEKCmZvciAoYiBpbiAxOmxlbmd0aChuYmlucykpIHsKICAjIGZvciAocyBpbiAxOmxlbmd0aChuc2ltKSkgewoKICAgIG1lc3NhZ2Uoc3ByaW50ZigiJCQkJCRSVU5JTkcgbG1lciAlaSIsIG5iaW5zW2JdKSkKICAgICMgZGJfb2Y3X25ld19KRUZGRSRWaWRlb1R5cGVfY29udHJhc3Rfc2FtcGxlPC0gc2FtcGxlKChyZXAoYygtLjUsIC41KSwgZWFjaCA9ICAxOTIwKSksIHJlcGxhY2UgPSBGQUxTRSkgCiAgICAgICAgI3J1biB0aGUgbW9kZWwgb24gdGhlIGN1cnJlbnQgdGltZSBiaW4gYW5kIHNpbXVsYXRpb24gc3VtYmVyCiAgICAgICAgbG1lcl9iaW5fcHVwICA8LSBsbWVyKHB1cF9iYXNDb3IgfiB2YWxlbmNlX2MgK01lYW5fZ3JheV96ICArKDEgKyBNZWFuX2dyYXlfeiB8IHNzaWQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMXxzdGltSUFQUyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFTUwgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyID09ICJMb3ciICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWJpbl9ubyA9PSBuYmluc1tiXSkpCgogICAgICAgICNzdG9yZSByZXN1bHRzIGZyb20gdGhlIHNpbXVsYXRpb24KICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnk8LSBzdW1tYXJ5KGxtZXJfYmluX3B1cCkKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9sb3dbaSwxXTwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZXJlemVybzNbYl0gI3NhdmUgdGhlIGV4YWN0IHZhbHVlIG9mIHRpbWUgYmluCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXJfbG93W2ksMl08LSBsbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDFdICMgcwogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxfYW5kX2FyX2xvd1tpLDNdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDRdICMgdCBzdGF0aXN0aWMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9sb3dbaSw0XTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw1XSAjIHAgdmFsdWUKICAgICAgICAgICAgIyBzaW11bGF0ZWRfY2x1c3RlcnNfSkVGRkVbaSw2XTwtIG5zaW1bc10gI3N0b3JlIHNpbXVsYXRpb24gb3VudAogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92YWxfYW5kX2FyX2xvd1tpLDVdIDwtaWZlbHNlKGxlbmd0aChsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UsICdwYXNzJykKCiAgICAgaSA9IGkrMQp9CgpWaWV3KHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZhbF9hbmRfYXJfbmVnKQoKdGltZWNvdXJzZV9yZXN1bHRfZGZfdmFsX2FuZF9hcl9sb3clPiUKICBnZ3Bsb3QoYWVzKHRpbWViaW5zLCB0KSkrCiAgZ2VvbV9saW5lKHNpemUgPSAyKSsKICBnZW9tX2xpbmUoYWVzKHkgPSBwKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4wNSwgY29sb3IgPSAncmVkJywgc2l6ZSA9IDEuNSkKCgpgYGAKCgoKCnZlbG9jaXR5IGFuYWx5c2VzCmBgYHtyfQojIHRob3VnaHQgbWF5YmUgaXQgaGFzIHNvZW10aGluZyB0byB0byB3aXRoIHRoZSB2ZWxjaXR5LCB2ZWxvY2l0eSBpcyBzaWRkZXJlbnQKCmluc3RhbGwucGFja2FnZXMoInBzcGxpbmUiKQpsaWJyYXJ5KHBzcGxpbmUpCgpwcmVkaWN0KHNtLnNwbGluZSh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJHRpbWVyZXplcm8zLCAKICAgICAgICAgICAgICAgICAgdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCRwdXBfYmFzQ29yKSwgCiAgICAgICAgdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCR0aW1lcmV6ZXJvMywgMSkKCkQodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCRwdXBfYmFzQ29yLCAneCcpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3Cgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3IDwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcgJT4lCiAgIyBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgIyBzdWJzZXQodmFsZW5jZWFyb3VzYWxfb3V0bGllcnMgPT0gVFJVRSkgJT4lCiAgIyBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgc3RpbUlBUFMpICU+JQogIG11dGF0ZShwdXBfdmVsb2NpdHkgPSAoYWJzKGxhZyhwdXBfYmFzQ29yKS1wdXBfYmFzQ29yKS9hYnMobGFnKHRpbWVyZXplcm8zKS10aW1lcmV6ZXJvMykpKQogICMgbXV0YXRlKHB1cF92ZWxvY2l0eV9wZWFrID0gbWF4KHB1cF92ZWxvY2l0eSwgbmEucm0gPSBUUlVFKSkKCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JHB1cF92ZWxvY2l0eQoKIyBnbG9iYWwKdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsIDwtIGRhdGEuZnJhbWUodGltZWJpbnM9IHJlcChOQSwgMzApLCBFc3RpbWF0ZT0gcmVwKE5BLCAzMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQ9cmVwKE5BLCAzMCksIHA9cmVwKE5BLCAzMCksIGNvdj0gYXMuY2hhcmFjdGVyKHJlcChOQSwzMCkpKQoKCmkgPSAxCmIKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckcHVwX3ZlbG9jaXR5CgpsbWVyX2Jpbl9wdXAgIDwtIGxtZXIocHVwX3ZlbG9jaXR5IH4gYXJvdXNhbF9jICsgTWVhbl9ncmF5X3ogICsgKDEgKyBNZWFuX2dyYXlfeiB8IHNzaWQpLAogICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lYmluX25vID09IG5iaW5zWzJdKSkKCmZvciAoYiBpbiAyOmxlbmd0aChuYmlucykpIHsKICAjIGZvciAocyBpbiAxOmxlbmd0aChuc2ltKSkgewoKICAgIG1lc3NhZ2Uoc3ByaW50ZigiJCQkJCRSVU5JTkcgbG1lciAlaSIsIG5iaW5zW2JdKSkKICAgICMgZGJfb2Y3X25ld19KRUZGRSRWaWRlb1R5cGVfY29udHJhc3Rfc2FtcGxlPC0gc2FtcGxlKChyZXAoYygtLjUsIC41KSwgZWFjaCA9ICAxOTIwKSksIHJlcGxhY2UgPSBGQUxTRSkgCiAgICAgICAgI3J1biB0aGUgbW9kZWwgb24gdGhlIGN1cnJlbnQgdGltZSBiaW4gYW5kIHNpbXVsYXRpb24gc3VtYmVyCiAgICAgICAgbG1lcl9iaW5fcHVwICA8LSBsbWVyKHB1cF92ZWxvY2l0eSB+IGFyb3VzYWxfYyArIE1lYW5fZ3JheV96ICArICgxICsgTWVhbl9ncmF5X3ogfCBzc2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICFpcy5uYT09ICJNb3JlIG5lZ2F0aXZlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWViaW5fbm8gPT0gbmJpbnNbYl0pKQoKICAgICAgICAjc3RvcmUgcmVzdWx0cyBmcm9tIHRoZSBzaW11bGF0aW9uCiAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5PC0gc3VtbWFyeShsbWVyX2Jpbl9wdXApCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbFtpLDFdPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lcmV6ZXJvM1tiXSAjc2F2ZSB0aGUgZXhhY3QgdmFsdWUgb2YgdGltZSBiaW4KICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsW2ksMl08LSBsbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDFdICMgcwogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92ZWxbaSwzXTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw0XSAjIHQgc3RhdGlzdGljCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbFtpLDRdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDVdICMgcCB2YWx1ZQogICAgICAgICAgICAjIHNpbXVsYXRlZF9jbHVzdGVyc19KRUZGRVtpLDZdPC0gbnNpbVtzXSAjc3RvcmUgc2ltdWxhdGlvbiBvdW50CiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbFtpLDVdIDwtaWZlbHNlKGxlbmd0aChsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UsICdwYXNzJykKCiAgICAgaSA9IGkrMQp9CgoKVmlldyh0aW1lY291cnNlX3Jlc3VsdF9kZl92ZWwpCgoKCiMgd2hldGhlciBJIHVzZSBncm91bmQgdmFsZW5jZSwgc2VsZiB2YWxlbWNlIG9yIHRoaXMgc2FtcGxlIGF2ZXJhZ2UgdmFsZW5jZSwgSSBnZXQgdGhlIHNhbWUgcGF0dGVybnMKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbCU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjA1LCBjb2xvciA9ICdyZWQnLCBzaXplID0gMS41KQoKCiMgYXJvdXNhbCByYXRpbmcgaXMgcmVsYXRlZCB0byB2ZWxvY2l0eSBhcm91bmQgdGhlIHJlY292ZXJ5IHRpbWUgMToyaXMsIGFuZCBsYXRlciBhcm91bmQgNAoKCmBgYAoKClZlbG9jaXR5IGJ5IHZhbGVuY2UKYGBge3J9CgoKdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3BvcyA8LSBkYXRhLmZyYW1lKHRpbWViaW5zPSByZXAoTkEsIDMwKSwgRXN0aW1hdGU9IHJlcChOQSwgMzApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0PXJlcChOQSwgMzApLCBwPXJlcChOQSwgMzApLCBjb3Y9IGFzLmNoYXJhY3RlcihyZXAoTkEsMzApKSkKCgppID0gMQojIGIKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckcHVwX3ZlbG9jaXR5CgoKZm9yIChiIGluIDI6bGVuZ3RoKG5iaW5zKSkgewogICMgZm9yIChzIGluIDE6bGVuZ3RoKG5zaW0pKSB7CgogICAgbWVzc2FnZShzcHJpbnRmKCIkJCQkJFJVTklORyBsbWVyICVpIiwgbmJpbnNbYl0pKQogICAgIyBkYl9vZjdfbmV3X0pFRkZFJFZpZGVvVHlwZV9jb250cmFzdF9zYW1wbGU8LSBzYW1wbGUoKHJlcChjKC0uNSwgLjUpLCBlYWNoID0gIDE5MjApKSwgcmVwbGFjZSA9IEZBTFNFKSAKICAgICAgICAjcnVuIHRoZSBtb2RlbCBvbiB0aGUgY3VycmVudCB0aW1lIGJpbiBhbmQgc2ltdWxhdGlvbiBzdW1iZXIKICAgICAgICBsbWVyX2Jpbl9wdXAgIDwtIGxtZXIocHVwX3ZlbG9jaXR5IH4gYXJvdXNhbF9jICsgTWVhbl9ncmF5X3ogICsgKDEgIHwgc3NpZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAoMXxzdGltSUFQUyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFTUwgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQodG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyPT0gIk1vcmUgcG9zaXRpdmUiICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWJpbl9ubyA9PSBuYmluc1tiXSkpCgogICAgICAgICNzdG9yZSByZXN1bHRzIGZyb20gdGhlIHNpbXVsYXRpb24KICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnk8LSBzdW1tYXJ5KGxtZXJfYmluX3B1cCkKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3Bvc1tpLDFdPC0gdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyR0aW1lcmV6ZXJvM1tiXSAjc2F2ZSB0aGUgZXhhY3QgdmFsdWUgb2YgdGltZSBiaW4KICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3Bvc1tpLDJdPC0gbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiwxXSAjIHMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3Bvc1tpLDNdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDRdICMgdCBzdGF0aXN0aWMKICAgICAgICAgICAgdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3Bvc1tpLDRdPC1sbWVyX2Jpbl9wdXBfc3VtbWFyeVtbImNvZWZmaWNpZW50cyJdXVsyLDVdICMgcCB2YWx1ZQogICAgICAgICAgICAjIHNpbXVsYXRlZF9jbHVzdGVyc19KRUZGRVtpLDZdPC0gbnNpbVtzXSAjc3RvcmUgc2ltdWxhdGlvbiBvdW50CiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9wb3NbaSw1XSA8LWlmZWxzZShsZW5ndGgobG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsbWVyX2Jpbl9wdXBfc3VtbWFyeSRvcHRpbmZvJGNvbnYkbG1lNCRtZXNzYWdlLCAncGFzcycpCgogICAgIGkgPSBpKzEKfQoKIyAxMSBzaW5ndWxhcml0eSBjYXNlcwoKVmlldyh0aW1lY291cnNlX3Jlc3VsdF9kZl92ZWxfcG9zKQoKCgoKIyB3aGV0aGVyIEkgdXNlIGdyb3VuZCB2YWxlbmNlLCBzZWxmIHZhbGVtY2Ugb3IgdGhpcyBzYW1wbGUgYXZlcmFnZSB2YWxlbmNlLCBJIGdldCB0aGUgc2FtZSBwYXR0ZXJucwoKdGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX3BvcyU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjA1LCBjb2xvciA9ICdyZWQnLCBzaXplID0gMS41KQoKCiMgYXJvdXNhbCByYXRpbmcgaXMgcmVsYXRlZCB0byB2ZWxvY2l0eSBhcm91bmQgdGhlIHJlY292ZXJ5IHRpbWUgMSB0byAxLjYKCgoKYGBgCgoKCk5lZ2F0aXZlIHZlbG9jaXR5CgpgYGB7cn0KCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWcgPC0gZGF0YS5mcmFtZSh0aW1lYmlucz0gcmVwKE5BLCAzMCksIEVzdGltYXRlPSByZXAoTkEsIDMwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdD1yZXAoTkEsIDMwKSwgcD1yZXAoTkEsIDMwKSwgY292PSBhcy5jaGFyYWN0ZXIocmVwKE5BLDMwKSkpCgoKaSA9IDEKYgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaG5ldyRwdXBfdmVsb2NpdHkKCgpmb3IgKGIgaW4gMjpsZW5ndGgobmJpbnMpKSB7CiAgIyBmb3IgKHMgaW4gMTpsZW5ndGgobnNpbSkpIHsKCiAgICBtZXNzYWdlKHNwcmludGYoIiQkJCQkUlVOSU5HIGxtZXIgJWkiLCBuYmluc1tiXSkpCiAgICAjIGRiX29mN19uZXdfSkVGRkUkVmlkZW9UeXBlX2NvbnRyYXN0X3NhbXBsZTwtIHNhbXBsZSgocmVwKGMoLS41LCAuNSksIGVhY2ggPSAgMTkyMCkpLCByZXBsYWNlID0gRkFMU0UpIAogICAgICAgICNydW4gdGhlIG1vZGVsIG9uIHRoZSBjdXJyZW50IHRpbWUgYmluIGFuZCBzaW11bGF0aW9uIHN1bWJlcgogICAgICAgIGxtZXJfYmluX3B1cCAgPC0gbG1lcihwdXBfdmVsb2NpdHkgfiBhcm91c2FsX2MgKyBNZWFuX2dyYXlfeiAgKyAoMSB8IHNzaWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3Vic2V0KHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMj09ICJNb3JlIG5lZ2F0aXZlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWViaW5fbm8gPT0gbmJpbnNbYl0pKQoKICAgICAgICAjc3RvcmUgcmVzdWx0cyBmcm9tIHRoZSBzaW11bGF0aW9uCiAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5PC0gc3VtbWFyeShsbWVyX2Jpbl9wdXApCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWdbaSwxXTwtIHRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWhuZXckdGltZXJlemVybzNbYl0gI3NhdmUgdGhlIGV4YWN0IHZhbHVlIG9mIHRpbWUgYmluCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWdbaSwyXTwtIGxtZXJfYmluX3B1cF9zdW1tYXJ5W1siY29lZmZpY2llbnRzIl1dWzIsMV0gIyBzCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWdbaSwzXTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw0XSAjIHQgc3RhdGlzdGljCiAgICAgICAgICAgIHRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWdbaSw0XTwtbG1lcl9iaW5fcHVwX3N1bW1hcnlbWyJjb2VmZmljaWVudHMiXV1bMiw1XSAjIHAgdmFsdWUKICAgICAgICAgICAgIyBzaW11bGF0ZWRfY2x1c3RlcnNfSkVGRkVbaSw2XTwtIG5zaW1bc10gI3N0b3JlIHNpbXVsYXRpb24gb3VudAogICAgICAgICAgICB0aW1lY291cnNlX3Jlc3VsdF9kZl92ZWxfbmVnW2ksNV0gPC1pZmVsc2UobGVuZ3RoKGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICE9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG1lcl9iaW5fcHVwX3N1bW1hcnkkb3B0aW5mbyRjb252JGxtZTQkbWVzc2FnZSwgJ3Bhc3MnKQoKICAgICBpID0gaSsxCn0KCiMgMTEgc2luZ3VsYXJpdHkgY2FzZXMKClZpZXcodGltZWNvdXJzZV9yZXN1bHRfZGZfdmVsX25lZykKCgoKCiMgd2hldGhlciBJIHVzZSBncm91bmQgdmFsZW5jZSwgc2VsZiB2YWxlbWNlIG9yIHRoaXMgc2FtcGxlIGF2ZXJhZ2UgdmFsZW5jZSwgSSBnZXQgdGhlIHNhbWUgcGF0dGVybnMKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX3ZlbF9uZWclPiUKICBnZ3Bsb3QoYWVzKHRpbWViaW5zLCB0KSkrCiAgZ2VvbV9saW5lKHNpemUgPSAyKSsKICBnZW9tX2xpbmUoYWVzKHkgPSBwKSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC4wNSwgY29sb3IgPSAncmVkJywgc2l6ZSA9IDEuNSkKCgojIGFyb3VzYWwgcmF0aW5nIGlzIHJlbGF0ZWQgdG8gdmVsb2NpdHkgYXJvdW5kIHRoZSByZWNvdmVyeSB0aW1lIDEgdG8gMS42CgoKYGBgCgpBIGZldyBwbG90cyBmb3IgdmVsb2NpdHkKYGBge3J9CiAgZ2dwbG90KGFlcyh4ID0gdGltZXJlemVybzMsIHkgPSBwdXBfdmVsb2NpdHkpKSsKICBzdGF0X3Ntb290aChhZXMoZ3JvdXA9IG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiwgY29sb3IgPSBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpLCBmdW4gPSBtZWFuLGdlb20gPSAibGluZSIsCiAgICAgICAgICAgICAgIHNlID0gRiwgYWxwaGEgPSAuMSwgc2l6ZSA9IDEuNSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPW1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiwgY29sb3IgPSBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpLCBzaXplID0gMykrICAKdGhlbWVfY2xhc3NpYygpKwogIHlsYWIoIlB1cGlsIHZlbG9jaXR5IikrCiAgeGxhYigiVGltZSAocykiKSsKICAjIHAkZ3JhcGhzdHlsZSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwogIHhsaW0oMCw2KSsKICAgIyBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIpKwogICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpCgoKCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkdGltZXJlemVybzMKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgc3Vic2V0KHRpbWVyZXplcm8zPjEgKSAlPiUKICAjIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSklPiUKICBncm91cF9ieShzc2lkLCBzdGltSUFQUyklPiUKICBtdXRhdGUocHVwX3ZlbG9jaXR5ID0gKGFicyhsYWcocHVwX2Jhc0NvciktcHVwX2Jhc0NvcikpLyhhYnMobGFnKHRpbWVyZXplcm8zKS10aW1lcmV6ZXJvMykpKSU+JQogIG11dGF0ZShwdXBfdmVsb2NpdHlfcGVhayA9IG1heChwdXBfdmVsb2NpdHksIG5hLnJtID0gVFJVRSkpJT4lCiAgZ3JvdXBfYnkoc3NpZCxtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyh4ID0gbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyLCB5ID0gcHVwX3ZlbG9jaXR5KSkrCiAgIyBnZW9tX2ppdHRlcih3aWR0aCA9IC4xLCBhbHBoYSA9IC4xKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgdGhlbWVfY2xhc3NpYygpKwogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKCkrCiAgeWxhYigiUHVwaWwgdmVsb2NpdHkgKHopIikrCiAgeGxhYigiVGltZSAocykiKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpCgoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMikpJT4lCiAgc3Vic2V0KHRpbWVyZXplcm8zPjEpICU+JQogICMgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpKSU+JQogIGdyb3VwX2J5KHNzaWQsIHN0aW1JQVBTKSU+JQogIG11dGF0ZShwdXBfdmVsb2NpdHkgPSAoYWJzKGxhZyhwdXBfYmFzQ29yKS1wdXBfYmFzQ29yKSkvKGFicyhsYWcodGltZXJlemVybzMpLXRpbWVyZXplcm8zKSkpJT4lCiAgbXV0YXRlKHB1cF92ZWxvY2l0eV9wZWFrID0gbWF4KHB1cF92ZWxvY2l0eSwgbmEucm0gPSBUUlVFKSklPiUKICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMixtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKHggPSBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIsIHkgPSBwdXBfdmVsb2NpdHlfcGVhaykpKwogIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKSsKICB5bGFiKCJwZWFrIFB1cGlsIHZlbG9jaXR5ICh6KSIpKwogIHhsYWIoIlRpbWUgKHMpIikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKQogIAogIAoKYGBgCmBgYHtyfQp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVobmV3JT4lCiAgICBncm91cF9ieShtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UsIHRpbWViaW4yKSU+JQpzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXModGltZXJlemVybzMsIGNvcl9hcm91c19wdXAsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSkrCiAgIyBnZW9tX3MKICBzdGF0X3N1bW1hcnkoZnVuID0gbWVhbiwgZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgc3RhdF9zdW1tYXJ5KGFlcyh5ID0gY29yX2Fyb3VzX3B1cF9wdmFsKSwgZnVuID0gbWVhbiwgZ2VvbSA9ICdsaW5lJywgbGluZXR5cGUgPSAiZGFzaGVkIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjEsIGxpbmV0eXBlID0gImRhc2hlZCIpCiAgZ2VvbV9yZWN0KGFlcyh4bWluID0gdGltZXJlemVybzMsIHhtYXggPSBkcGx5cjo6bGVhZCh0aW1lcmV6ZXJvMyksIHltaW4gPS42MyAsIHltYXggPS42NiAsIGZpbGwgPSBwdmFsX3NpZ24pLCAKICAgICAgICAgICAgYWxwaGEgPSAwLjgpCiAgCiAgCiAgCiAgIyBzdGF0X3Ntb290aChhZXMoZ3JvdXAgPSBzc2lkKSwgc2UgPSBGLCBhbHBoYSA9IC4xKQogICMgbXV0YXRlKAogICMgICBtb2RlbCA9IG1hcChkYXRhLCB+bG0ocHVwX2Jhc0NvciB+IGFyb3VzYWxfYywgZGF0YSA9IC4pKSwKICAjICAgY29yID0gbWFwKGRhdGEsIHBvc3NpYmx5KAogICMgICAgIH50aWR5KGNvci50ZXN0KC54JHB1cF9iYXNDb3IsIC54JGFyb3VzYWxfYyksIDMpLCBvdGhlcndpc2UgPSBkYXRhLmZyYW1lKCkpCiAgIyAgICkKICAjICkKCgoKYGBgCgoKIyBzZWxmIGFyb3VzYWwKCmBgYHtyfQoKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKGdyb3VuZF9hcm91c2FsX2xhYikpJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZXJlemVybzMsIHkgPSBwdXBfYmFzQ29yKSkrCiAgc3RhdF9zbW9vdGgoYWVzKGdyb3VwPSBncm91bmRfYXJvdXNhbF9sYWIsIGNvbG9yID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSwgZnVuID0gbWVhbixnZW9tID0gImxpbmUiLAogICAgICAgICAgICAgICBzZSA9IEYsIGFscGhhID0gLjEsIHNpemUgPSAxLjUpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD1ncm91bmRfYXJvdXNhbF9sYWIsIGNvbG9yID0gZ3JvdW5kX2Fyb3VzYWxfbGFiKSwgc2l6ZSA9IDMpKyAgCnRoZW1lX2NsYXNzaWMoKSsKICB5bGFiKCJQdXBpbCBzaXplICh6KSIpKwogIHhsYWIoIlRpbWUgKHMpIikrCiAgIyBwJGdyYXBoc3R5bGUrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiRGFyazIiKSsKICB4bGltKDAsNikrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKQoKCgpgYGAKCgpgYGB7cn0KCiMgcGxvdCB3aXRoIHZhbGVuY2UKdG1wLmRmNF9mdWxsX3N0aW1fZG93bnNfanVuMjAyMV93aXRoX2JlaCAlPiUKICBzdWJzZXQoIWlzLm5hKGdyb3VuZF9hcm91c2FsX2xhYikpJT4lCiAgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIHRpbWViaW4yKSU+JQogIGdncGxvdChhZXMoeCA9IHRpbWVyZXplcm8zLCB5ID0gcHVwX2Jhc0NvcikpKwogIHN0YXRfc21vb3RoKGFlcyhncm91cD0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIGNvbG9yID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpLCBmdW4gPSBtZWFuLGdlb20gPSAibGluZSIsCiAgICAgICAgICAgICAgIHNlID0gRiwgc2l6ZSA9IDEuNSkrCiAgIyBzdGF0X3Ntb290aChhZXMoZ3JvdXA9Z3JvdW5kX3ZhbGVuY2VfbGFiLCBjb2xvciA9IGdyb3VuZF92YWxlbmNlX2xhYiksIHNpemUgPSAzKSsgIAp0aGVtZV9jbGFzc2ljKCkrCiAgeWxhYigiUHVwaWwgc2l6ZSAoeikiKSsKICB4bGFiKCJUaW1lIChzKSIpKwogICMgcCRncmFwaHN0eWxlKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgeGxpbSgwLDYpCgoKCnRlc3Q8LSBjb3IudGVzdChkYl8yMDIxX3B1cGlsX3N1bW0kaHJfaW50ZXJwLGRiXzIwMjFfcHVwaWxfc3VtbSRwdXBfYmFzQ29yKQoKdGVzdCRwLnZhbHVlCnRtcC5kZjRfZnVsbF9zdGltX2Rvd25zX2p1bjIwMjFfd2l0aF9iZWgkc3NpZF9ncm91bmRfdmFsZW5jZTwtIHBhc3RlMCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJHNzaWQsIHBhc3RlMCh0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoJGdyb3VuZF9hcm91c2FsX2xhYikpCgp0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoICU+JQogIHN1YnNldCghaXMubmEoc2VsZl9hcm91c2FsX2xhYikpJT4lCiAgCiAgCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdAogIAogIAogIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIGdyb3VuZF92YWxlbmNlX2xhYiwgdGltZWJpbjIpJT4lCiAgICBtdXRhdGUoY29ydGVzdCA9IGNvci50ZXN0KGFyb3VzYWxfYywgcHVwX2Jhc0NvcikkZXN0aW1hdGUpJT4lCiAgbXV0YXRlKHBjb3J0ZXN0ID0gY29yLnRlc3QoYXJvdXNhbF9jLCBwdXBfYmFzQ29yKSRwLnZhbHVlKSU+JQogIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIHNlbGZfYXJvdXNhbF9sYWIsIHRpbWViaW4yKSU+JQogICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZXJlemVybzMsIHkgPSBjb3J0ZXN0KSkrCgogIHN0YXRfc21vb3RoKGFlcyhncm91cD0gc2VsZl9hcm91c2FsX2xhYiwgY29sb3IgPSBzZWxmX2Fyb3VzYWxfbGFiKSwgZnVuID0gbWVhbixnZW9tID0gImxpbmUiLAogICAgICAgICAgICAgICBzZSA9IEYsIHNpemUgPSAxLjUpKwp0aGVtZV9jbGFzc2ljKCkrCiAgeWxhYigiUHVwaWwgc2l6ZSAoeikiKSsKICB4bGFiKCJUaW1lIChzKSIpKwogICMgcCRncmFwaHN0eWxlKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjA1LCBsaW5ldHlwZSA9ICJkYXNoZWQiKSsKICB4bGltKDAsNikKCgojIGRvZXMgYXJvdXNpbmcgc3RpbXVsaSBpbXBhaXJzIGFwcHJhaXNhbAoKCiB0bXAuZGY0X2Z1bGxfc3RpbV9kb3duc19qdW4yMDIxX3dpdGhfYmVoICU+JQogICBnZ3Bsb3QoYWVzKGdyb3VuZF9hcm91c2FsX2xhYiwgQlJJR0hUTkVTUykpKwogICBnZW9tX2JveHBsb3QoKSsKICAgZ2VvbV9wb2ludCgpKwogICAjIHN0YXRfc3VtbWFyeShnZW9tID0gJ2JveHBsb3QnKSsKICAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKQpgYGAKCgoKYGBge3J9CiBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChwdXBpbF9vdXRsaWVyID09IEZBTFNFICYgYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgJiAhaXMubmEoQWxleGl0aHltaWEpICYgc3NpZCE9IDYxMCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCxBbGV4aXRoeW1pYSwgaXNfdmFsZW5jZV9oaWdoKSU+JQogICBncm91cF9ieShzc2lkLEFsZXhpdGh5bWlhLCBtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UpJT4lCiAgICBtdXRhdGUoY29ydGVzdCA9IGNvci50ZXN0KGFyb3VzYWxfYywgcHVwX2Jhc0NvcikkZXN0aW1hdGUpJT4lCiAgIGdyb3VwX2J5KHNzaWQsQWxleGl0aHltaWEsIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSwgc2VsZl9hcm91c2FsX2xhYiklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAgICAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UsIGNvcnRlc3QsIGNvbG9yID0gbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iKSsKICAKICAgIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogICAgICAgIHN0YXRfc3VtbWFyeSggZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICAgICAgICAjIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICdsaW5lJykrCiAgICB5bGFiKCJSIHB1cGlsIHZzIHNlbGYgcmVwb3J0IGFyb3VzYWwiKSsKICAgIyBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhwYWlyZWQgPSBUUlVFKSsKICAjIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gbXlfY29tcGFyaXNvbnMsIHBhaXJlZCA9IFRSVUUpCiAgICAgIGZhY2V0X2dyaWQofnNlbGZfYXJvdXNhbF9sYWIpCgpgYGAKCgoKU0NSCgpgYGB7cn0KCnVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JHNzaWQpClZpZXcoZmxhZ19wb3NfbmVnKQpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JG1lZGlhbnNwbGl0X3NlbGZfYXJvdXNhbCA8LSBpZl9lbHNlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkYXJvdXNhbD4gbWVkaWFuKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkYXJvdXNhbCwgbmEucm0gPSBUUlVFKSwgIkhpZ2giLCAiTG93IikKCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRtZWRpYW5zcGxpdF9zZWxmX2Fyb3VzYWxfdGhpc3NhbXBsZSA8LSBpZl9lbHNlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkYXJvdXNhbD4gbWVkaWFuKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkQXJvdXNhbE1lYW5UaGlzU2FtcGxlLCBuYS5ybSA9IFRSVUUpLCAiSGlnaCIsICJMb3ciKQoKdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QyJHNzaWQpCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250PC0gc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIHNzaWRfbnVtPDUwMCkKCm5yb3coZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCkKIyAyMjMzCiMgbnJvdyhsZWZ0X2pvaW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwgZmxhZ19wb3NfbmVnKSkKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQ8LSBsZWZ0X2pvaW4oZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwgZmxhZ19wb3NfbmVnKQoKCgp1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRzdGltRGVzY3JpcHRpb24pCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQgJT4lCiAgc3Vic2V0KHNzaWRfbnVtPCA1MDApJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSApJT4lCiAgICAgICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAgZ3JvdXBfYnkoc3NpZCklPiUKICBtdXRhdGUoQklPX0NEQS5TQ1JfeiA9IHNjYWxlKChCSU9fQ0RBLlNDUikpWywxXSklPiUKICB1bmdyb3VwKCklPiUKICAgIGdyb3VwX2J5KHNzaWQsY29yX3Bvc19uZWdfZGlmZl9sYWIsIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9zZWxmX3ZhbGVuY2UsIEJJT19DREEuU0NSX3opKSsKICAgICAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpKwogIAogIAogICAgICMgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC4yKSsKICBnZW9tX2ppdHRlcih3aWR0aCA9IC4yLCBhbHBoYSA9IC4yKSsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGNvbG9yID0gImdyYXkiLCBhbHBoYSA9IC4xKSsKICAjIGdlb21fYm94cGxvdChhbHBoYSA9IC4xKSsKICAjIGZhY2V0X2dyaWQofmNvcl9wb3NfbmVnX2RpZmZfbGFiKSsKICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucygpCgpCSU9fQ0RBLklTQ1JfegoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCAlPiUKICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShCSU9fVFRQLkFtcFN1bV96ID0gc2NhbGUoQklPX1RUUC5BbXBTdW0sIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSlbLDFdKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhhcm91c2FsX2MsIEJJT19UVFAuQW1wU3VtX3opKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250ICU+JQogIGdyb3VwX2J5KHNzaWQsbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKSU+JQogICMgbXV0YXRlKEJJT19UVFAuQW1wU3VtX3ogPSBzY2FsZShCSU9fVFRQLkFtcFN1bSwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0pJT4lCiAgIyBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbCwgQklPX0NEQS5JU0NSX3opKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKQoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCAlPiUKICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbF9jLCBCSU9fQ0RBLlBoYXNpY01heF96LCBjb2xvciA9bWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgoKCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250ICU+JQogIGdyb3VwX2J5KHNzaWQsZ3JvdW5kX2Fyb3VzYWxfbGFiKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhhcm91c2FsX2MsIEJJT19DREEuUGhhc2ljTWF4X3osIGNvbG9yID1ncm91bmRfYXJvdXNhbF9sYWIpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICAKICAKICAKICAKCgpgYGAKCiMgc2NyIG1vZGVsCgo8IS0tICMgYXZlcmFnZSBhcm91YWwgYW5kIHJhdGluZyBvdmVyIGFsbCB0cmlhbHMgZG9uJ3QgdHJhY2sgd2VsbCB0aGUgZXhwZWN0ZWQgYXJvdXNhbCByZWxhdGlvbiAtLT4KYGBge3J9Cgp1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRjb25kaXRpb24pCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdXNhbF9zY3IgPC0gbG1lcihsb2coQklPX0NEQS5TQ1IrLjEpIH4gYXJvdXNhbF9jKlRBU2MgKygxfHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcF9hcm91c2FsX291dGxlciA9PSBGQUxTRSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlID09ICJNb3JlIHBvc2l0aXZlIikpCgpzdW1tYXJ5KHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdXNhbF9zY3IpCmFub3ZhKHB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdXNhbF9waGFzX21heCkKCgpCSU9fQ0RBLlBoYXNpY01heAoKCnB1cGlsX2Fyb3VzYWxfZmluZGluZ3MkYXJvdXNhbF9zY3IgPC0gbG1lcihCSU9fQ0RBLlBoYXNpY01heF96IH4gdmFsZW5jZV9jICsoMSthcm91c2FsX2N8c3NpZCksCiAgICAgICAgICAgICAgICAgICAgICAgIFJFTUwgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwX2Fyb3VzYWxfb3V0bGVyID09IEZBTFNFKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSA9PSAiTW9yZSBwb3NpdGl2ZSIpKQoKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJGFyb3VzYWxfc2NyKQphbm92YShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJGFyb3VzYWxfcGhhc19tYXgpCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCAlPiUKICBncm91cF9ieShzc2lkLCBjb3JfcG9zX25lZ19kaWZmX2xhYiklPiUKICBnZ3Bsb3QoYWVzKGNvcl9wb3NfbmVnX2RpZmZfbGFiLCBUQVMpKSsKICBnZW9tX3BvaW50KCkrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpCmBgYAoKc3VtbWFyeShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJGFyb3VzYWxfc2NyKQphbm92YShwdXBpbF9hcm91c2FsX2ZpbmRpbmdzJGFyb3VzYWxfcGhhc19tYXgpCgoKdGVzdDwtIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBwcF9hcm91c2FsX291dGxlciA9PSBGQUxTRSAmIHNzaWQgPT0gMzEwKQp0ZXN0JEFsZXhpdGh5bWlhCnRhYmxlKHRlc3QkbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKQoKIyB0cnkgdGhlIGFub3ZhIGdyb3VwaW5nCmBgYHtyfQoKYWZleDo6YW92X2V6KGRhdGEgPSAoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlciA9PSBGQUxTRSklPiUKICAgICAgIyBzdWJzZXQoaXNfc2NyX25vbnJlc3BvbmRlciA9PSBGQUxTRSApJT4lCiAgICAgIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICAgICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICAgICAgIyBncm91cF9ieShzc2lkLCBBbGV4aXRoeW1pYSxtZWRpYW5zcGxpdF9zZWxmX2Fyb3VzYWwsIG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSklPiUKICAgICAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSkpLAogICAgaWQgPSAic3NpZCIsCiAgICBiZXR3ZWVuID0gTlVMTCwKICAgIHdpdGhpbiA9IGMoIm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlIiksCiAgICBkdiA9ICJCSU9fQ0RBLlNDUl96IikKCgoKCmNvbG5hbWVzKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QpCgoKZ2djb3JycGxvdDo6Z2djb3JycGxvdChjb3IoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdFssYygxOSwxMTUsMTI1OjEyOCwyNywyNildLCB1c2UgPSAiY29tcGxldGUiKSkKCmBgYAoKCiAgICAKQklPX0NEQS5TQ1JfegoKIyBpbmRvdmlkdWFsIHBsb3RzCmBgYHtyfQoKZmFjZXRfaGlzdF9zY3I8LSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIHN1YnNldChzc2lkID4gMzAzKSU+JQogIHN1YnNldChhcm91c2FsX291dGxlciA9PSBGQUxTRSApJT4lCiAgICAgICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICBnZ3Bsb3QoYWVzKGxvZzFwKEJJT19DREEuU0NSKzEpKSkrCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9ICkrCiAgZmFjZXRfd3JhcCh+c3NpZCkKCmBgYAoKCgojIHdoYXQncyB1cCB3aXRoIG5vbiByZXNwb25kZXJzCgojIDMxMgojIDMxOCBvbmx5IG9uZSByc3BpbnNlPwojIDMyMAojIDMyMQojIDMyNwojIDMyOQojIDMzMgojIDMzNSAob25seSBvbmUgcmVzcG9uc2UpCiMgMzQyCiMgMzQzCiMgNjAwCiMgNjAzCiMgNjA2IChvbmx5IG9uZSByZXNwb25zZSkKIyA2MDgKIyA5MDAKIyA1Ni0gMTUKCiMgdGhhdCB3b3VsZCBsZWF2ZSB1cyB3aXRoIDQxIHBlb3BsZQoKYGBge3J9CnVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JHNzaWQpCgpyYW5nZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JEJJT19DREEuU0NSLCBuYS5ybSA9IFRSVUUpCgptZWFuKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QkQklPX0NEQS5TQ1IsIG5hLnJtID0gVFJVRSkKc2QoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRCSU9fQ0RBLlNDUiwgbmEucm0gPSBUUlVFKQoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCU+JQogIGdncGxvdChhZXMoQklPX0NEQS5TQ1IpKSsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gNTAwKQogIHhsaW0oMCwuMDEpCiAgCiAgCiAgCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QlPiUKICBzdWJzZXQoc3NpZCA9PSAzMTIpJT4lCiAgZ2dwbG90KGFlcyhCSU9fQ0RBLkFtcFN1bSkpKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSA1MDApKwogIHhsaW0oMCwuMDUpCgpgYGAKCgpgYGB7cn0KZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCRpc19zY3Jfbm9ucmVzcG9uZGVyPC0gaWZfZWxzZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0JEJJT19DREEuQW1wU3VtPCAuMSwgVFJVRSwgRkFMU0UpCgogZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICBzdWJzZXQoc3NpZCA+IDMwMyklPiUKICBzdWJzZXQoYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgKSU+JQogICAgICAgc3Vic2V0KCFpcy5uYShBbGV4aXRoeW1pYSkpJT4lCiAgZ2dwbG90KGFlcyhsb2cxcChCSU9fQ0RBLlNDUisxKSkpKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSApKwogICBmYWNldF9ncmlkKH5pc19zY3Jfbm9ucmVzcG9uZGVyKQogIGZhY2V0X3dyYXAofnNzaWQpCiAgCiAgCiAgCiAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCU+JQogICAgZ3JvdXBfYnkoc3NpZCxpc19zY3Jfbm9ucmVzcG9uZGVyKSU+JQogICAgbXV0YXRlKHNjcl9ub25yZXNwX3Byb3AgPSBuKCkpJT4lCiAgICAgIGdyb3VwX2J5KHNzaWQpJT4lCiAgICAgbXV0YXRlKHNjcl9ub25yZXNwX3Byb3AgPSBzY3Jfbm9ucmVzcF9wcm9wL24oKSklPiUKICAgIGdncGxvdChhZXMoYXMuZmFjdG9yKHNzaWQpLCBzY3Jfbm9ucmVzcF9wcm9wKSkrCiAgICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjIsIHdpZHRoID0gLjUpCiAgCiAgCiMgdGVzdDwtICBzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCwgc3NpZCA9PSAzMjEpCiAgICAKCiAgCiAgdGFibGUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRpc19zY3Jfbm9ucmVzcG9uZGVyKQogIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQgJT4lCiAgICBzdWJzZXQoaXNfc2NyX25vbnJlc3BvbmRlciAhPSBGQUxTRSklPiUKICAgIHN1YnNldChwcF9hcm91c2FsX291dGxlciA9PSBGQUxTRSklPiUKICAgIHN1YnNldCghc3NpZCAlaW4lIGMoIjMwNCIsIjMyMSIsICIzMjMiLCAiMzE4IiwiMzM5IiwiMzMxIiwiMzI1IikpJT4lCiAgIyBzdWJzZXQoIGFyb3VzYWxfb3V0bGVyID09IEZBTFNFICklPiUKICAgICAgIHN1YnNldCghaXMubmEoQWxleGl0aHltaWEpKSU+JQogICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShCSU9fQ0RBLlNDUl96ID0gc2NhbGUobG9nMXAoQklPX0NEQS5QaGFzaWNNYXggKy4xKSlbLDFdKSU+JQogICMgdW5ncm91cCgpJT4lCiAgICBncm91cF9ieShzc2lkLCBBbGV4aXRoeW1pYSxtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIsIG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiklPiUKICAgIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICAjIGdyb3VwX2J5KHNzaWQpJT4lCiAgICAjIG11dGF0ZShTQ1JfdHJlbmQgPSBCSU9fQ0RBLlNDUl96W21lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsID09ICJIaWdoZXIgYXJvdXNhbCJdIC0KICAgICAgICAgICAgICMgQklPX0NEQS5TQ1JfelttZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCA9PSAiTG93ZXIgYXJvdXNhbCJdKQogICAgIyBtdXRhdGUodHJlbmRzY3IgPSBpZl9lbHNlKFNDUl90cmVuZD4gMCwgImhpZ2ggdG8gaGlnaCIsICJoaWdoIHRvIGxvdyIpKQogIAogICAgIyBncm91cF9ieShzc2lkLCBBbGV4aXRoeW1pYSxtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCx0cmVuZHNjciklPiUKICAgICMgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiwgQklPX0NEQS5TQ1JfeikpKwogICAgICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnKSsKICAKICAgICAjIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuMikrCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAuMiwgYWxwaGEgPSAuMikKICAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikKICAgICMgZ2VvbV9ib3hwbG90KGFscGhhID0gLjEpCiAgICAjIGdlb21fdGV4dChhZXMobGFiZWwgPSBzc2lkKSkKICAgIGZhY2V0X2dyaWQofnRyZW5kc2NyKQogICAgIyB5bGltKC0xLDEpCiAgCiAgCjMwNCwgMzE4LCAzMzksIDMzMSwzMjUKCgoKc2NyX21vZGVsczwtIGxpc3QoKQoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCAlPiUKICAgIHN1YnNldChpc19zY3Jfbm9ucmVzcG9uZGVyID09IEZBTFNFKSU+JQogICAgc3Vic2V0KHBwX2Fyb3VzYWxfb3V0bGVyID09IEZBTFNFKSU+JQogICAgc3Vic2V0KCFzc2lkICVpbiUgYygiMzA0IiwiMzIxIiwgIjMyMyIsICIzMTgiLCIzMzkiLCIzMzEiLCIzMjUiKSkKICAjIHN1YnNldCggYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UgKSU+JQoKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnRfc2NyX2V4Y2x1ZGluZ19hdHlwaWNhbDwtIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQlPiUKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2V0KCFzc2lkICVpbiUgYygiMzA0IiwiMzIxIiwgIjMyMyIsICIzMTgiLCIzMzkiLCIzMzEiLCIzMjUiKSkKICAjIHN1YnNldChpc19zY3Jfbm9ucmVzcG9uZGVyID09IEZBTFNFKSU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKEJJT19DREEuUGhhc2ljTWF4X3ogPSBzY2FsZShCSU9fQ0RBLlBoYXNpY01heCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0pJT4lCiBtdXRhdGUodmFsZW5jZV96ID0gc2NhbGUodmFsZW5jZSwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0pJT4lCiAgICBtdXRhdGUoYXJvdXNhbF96ID0gc2NhbGUoYXJvdXNhbCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBUUlVFKVssMV0pCgoKc2NyX21vZGVscyRzY3JfZXhjbHVkaW5nX2F0eXBpY2FsPC0gbG1lcihsb2coQklPX0NEQS5QaGFzaWNNYXgrLjEpIH4gdmFsZW5jZV96ICsgYXJvdXNhbF96KwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8IHNzaWQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgc3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250X3Njcl9leGNsdWRpbmdfYXR5cGljYWwpCgoKc2NyX21vZGVscyRzY3JfZXhjbHVkaW5nX2F0eXBpY2FsPC0gbG1lcihsb2coQklPX0NEQS5QaGFzaWNNYXgrLjEpIH4gdmFsZW5jZV9jICsgYXJvdXNhbF9jKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8IHNzaWQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgc3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCkKICAgICAgICAgICAgICAgICAgICAgICAgIyBzdWJzZXQoIXNzaWQgJWluJSBjKCIzMDQiLCIzMjEiLCAiMzIzIiwgIjMxOCIsIjMzOSIsIjMzMSIsIjMyNSIpKSU+JQogIHN1YnNldChpc19zY3Jfbm9ucmVzcG9uZGVyICE9IEZBTFNFKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAKc3VtbWFyeShzY3JfbW9kZWxzJHNjcl9leGNsdWRpbmdfYXR5cGljYWwpICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgCihkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JT4lCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNldCghc3NpZCAlaW4lIGMoIjMwNCIsIjMyMSIsICIzMjMiLCAiMzE4IiwiMzM5IiwiMzMxIiwiMzI1IikpKSkKCnN1bW1hcnkoc2NyX21vZGVscyRzY3JfZXhjbHVkaW5nX2F0eXBpY2FsKQpgYGAKPCEtLSBvbmUgb2YgdGhlIHdvcnJpZXMgSSBoYWQgd2FzIHRoYXQgbWF5YmUgdGhlcmUgd2FzIGEgYmlhcyBzdWNoIHRoYXQgdmFsZW5jZSB3YXMgY29uZm91bmRlZCB3aXRoIGFyb3VzYWwsIGJ1dCBpZiB0aGlzIHdhcyB0cnVlLCB0aGVuIHBvc2l0aXZlIHN0aW11bGkgd291bDtkIGJlIHJhdGVkIGFzIG1vcmUgYXJvdXNpbmcgLS0+CiAgCiAgCiAgICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICAgc3Vic2V0KGlzX3Njcl9ub25yZXNwb25kZXIgPT0gRkFMU0UpJT4lCiAgICBzdWJzZXQocHBfYXJvdXNhbF9vdXRsZXIgPT0gRkFMU0UpJT4lCiAgc3Vic2V0KCBhcm91c2FsX291dGxlciA9PSBGQUxTRSApJT4lCiAgICAgICBzdWJzZXQoIWlzLm5hKEFsZXhpdGh5bWlhKSklPiUKICAgZ3JvdXBfYnkoc3NpZCklPiUKICBtdXRhdGUoQklPX0NEQS5TQ1JfeiA9IHNjYWxlKGxvZzFwKEJJT19DREEuUGhhc2ljTWF4ICsuMSkpWywxXSklPiUKICAgICAgbXV0YXRlKGFyb3VzYWxfeiA9IHNjYWxlKGFyb3VzYWwgKy4xKSklPiUKICB1bmdyb3VwKCklPiUKICAgICMgZ3JvdXBfYnkoc3NpZCwgQWxleGl0aHltaWEsbWVkaWFuc3BsaXRfc2VsZl9hcm91c2FsKSU+JQogICAgIyBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbF96LCBCSU9fQ0RBLlNDUl96KSkrCiAgICAgIGdlb21fcG9pbnQoKSsKICAgICAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBzc2lkKSxtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICAgICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICAgICBmYWNldF9ncmlkKH5ncm91bmRfYXJvdXNhbF9sYWIpCiAgCiAgICAgIyBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjIpKwogIGdlb21faml0dGVyKHdpZHRoID0gLjIsIGFscGhhID0gLjIpKwogICAgeWxpbSgtMSwxKQogIAogICMgcGFuZWwgZm9yIG1hbnkgZm9sa3MKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICMgc3Vic2V0KHNzaWQgPT0gMzE0KSU+JQogICAgZ3JvdXBfYnkoc3NpZCklPiUKICAgIG11dGF0ZShCSU9fQ0RBLlNDUl96ID0gc2NhbGUobG9nMXAoQklPX0NEQS5QaGFzaWNNYXggKy4xKSlbLDFdKSU+JQogICAgbXV0YXRlKGFyb3VzYWxfeiA9IHNjYWxlKGFyb3VzYWwgKy4xKSklPiUKICBnZ3Bsb3QoYWVzKGFyb3VzYWxfeixCSU9fQ0RBLlNDUl96LCBjb2xvciA9bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgLCBzaGFwZSA9bWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwpKSsKICAgIGdlb21fcG9pbnQoKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgICBmYWNldF93cmFwKH5zc2lkKSsKICAgIGdncHVicjo6c3RhdF9jb3IoKQogIAogICAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCAlPiUKICAjIHN1YnNldChzc2lkID09IDMxNCklPiUKICAgIGdyb3VwX2J5KHNzaWQpJT4lCiAgICBtdXRhdGUoQklPX0NEQS5TQ1JfeiA9IHNjYWxlKGxvZzFwKEJJT19DREEuUGhhc2ljTWF4ICsuMSkpWywxXSklPiUKICAgIG11dGF0ZShhcm91c2FsX3ogPSBzY2FsZShhcm91c2FsICsuMSkpJT4lCiAgZ2dwbG90KGFlcyhwdXBfYmFzQ29yLEJJT19DREEuU0NSX3opKSsKICAgIGdlb21fcG9pbnQoKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgICBmYWNldF93cmFwKH5zc2lkKSsKICAgIGdncHVicjo6c3RhdF9jb3IoKQogICAgCiAgICAKICAgICAgICBkYl9mdWxsICU+JQogICMgc3Vic2V0KHNzaWQgPT0gMzE0KSU+JQogICAgZ3JvdXBfYnkoc3NpZCklPiUKICAgIG11dGF0ZShCSU9fTWVhbl9IUiA9IHNjYWxlKEJJT19NZWFuX0hSLCBzY2FsZSA9IEZBTFNFKVssMV0pJT4lCiAgICBtdXRhdGUoYXJvdXNhbF96ID0gc2NhbGUoYXJvdXNhbCArLjEpKSU+JQogIGdncGxvdChhZXMoQklPX01lYW5fSFIsbG9nMXAoQklPX0NEQS5QaGFzaWNNYXgrLjEpKSkrCiAgICBnZW9tX3BvaW50KCkrCiAgICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBzc2lkKSxtZXRob2QgPSAnbG0nLCBzZSA9IEYpCiAgICBmYWNldF93cmFwKH5zc2lkKSsKICAgIGdncHVicjo6c3RhdF9jb3IoKQogICAgCiAgICAKICAgIAogICAgCgoKTGV0J3MgdHJ5IHNvbWUgMyBkIHZpc3VhbGlzYXRpb25zCmNvbnRpbnVlIGhlcmUKCgpgYGBge3J9CgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCAlPiUKICBncm91cF9ieShzc2lkLCBtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2Usc2NyX3V0bCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIHN1YnNldChzY3JfdXRsID09ICJub3RvdXRsaWVyIiklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsICwgQklPX0NEQS5QaGFzaWNNYXhfeikpKwogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuMSwgd2lkdGggPSAuMSkrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpKwogIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBzc2lkKSwgZ2VvbSA9ICJsaW5lIiwgYWxwaGEgPSAuMSkrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCU+JQogIGdncGxvdChhZXMoQklPX0NEQS5QaGFzaWNNYXhfeikpKwogIGdlb21faGlzdG9ncmFtKCkKCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250PC0gZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCU+JQogIG11dGF0ZShzY3JfdXRsID0gaWZfZWxzZShCSU9fQ0RBLlBoYXNpY01heF96ID4gNSwgIm91dGxpZXIiLCAibm90b3V0bGllciIpKQogIApgYGAKCiAgIyArIGFyb3VzYWxfYwogIApgYGB7cn0Kc2NyX21vZGVscyRzY3JfZXhjbHVkaW5nX2F0eXBpY2FsPC0gbG1lcihsb2coQklPX0NEQS5BbXBTdW1fY29sbGFwc2VkKy4xKSB+ICBhcm91c2FsX2MqdmFsZW5jZV9jICogVEFTYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCBzY3JfdXRsID09ICJub3RvdXRsaWVyIikpCgoKc3VtbWFyeShzY3JfbW9kZWxzJHNjcl9leGNsdWRpbmdfYXR5cGljYWwpCnBsb3Qoc2NyX21vZGVscyRzY3JfZXhjbHVkaW5nX2F0eXBpY2FsKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHNjcl9tb2RlbHMkc2NyX2V4Y2x1ZGluZ19hdHlwaWNhbCwgcHJlZCA9IGFyb3VzYWxfYywgbW9keCA9IHZhbGVuY2VfYywgbW9kMiA9IFRBU2MpCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCU+JQogIGdncGxvdChhZXMoKSkKCgpzY3JfbW9kZWxzJHNjcjE8LSBsbWVyKGxvZyhCSU9fQ0RBLlBoYXNpY01heF9jb2xsYXBzZWQrLjEpIH4gIGFyb3VzYWxfYyp2YWxlbmNlX2MgKiBUQVNjKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8IHNzaWQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgc3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAgc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQsIHNjcl91dGwgPT0gIm5vdG91dGxpZXIiKSkKCnN1bW1hcnkoc2NyX21vZGVscyRzY3IxKQpzY3JfbW9kZWxzJHNjcjEuMjwtIGxtZXIobG9nMXAoQklPX0NEQS5QaGFzaWNNYXgrLjEpIH4gIFRBU2MqYXJvdXNhbF9jICogdmFsZW5jZV9jKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgfCBzc2lkKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgc3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAgc3Vic2V0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QsIEdyb3VwID09ICJOVCIsICFpcy5uYShBbGV4aXRoeW1pYSkpKQoKdW5pcXVlKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3Qkc3NpZCkKc3VtbWFyeShzY3JfbW9kZWxzJHNjcjEuMikKCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogIGdyb3VwX2J5KHNzaWQsR3JvdXApJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBzdWJzZXQoR3JvdXAgPT0gIk5UIiklPiUKICBnZ3Bsb3QoYWVzKFRBUykpKwogIGdlb21faGlzdG9ncmFtKCkKCmludGVyYWN0aW9uczo6aW50ZXJhY3RfcGxvdChzY3JfbW9kZWxzJHNjcjEsIHByZWQgPSBhcm91c2FsX2MsIG1vZHggPSB2YWxlbmNlX2MsIG1vZDIgPSBUQVNjKQoKCgpzY3JfbW9kZWxzJHNjcjEuMTwtIGxtZXIoQ0RBLlBoYXNpY01heCB+ICBhcm91c2FsX2MqdmFsZW5jZV9jICogVEFTYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCBzY3JfdXRsID09ICJub3RvdXRsaWVyIikpCgoKc3VtbWFyeShzY3JfbW9kZWxzJHNjcjEuMSkKCmludGVyYWN0aW9uczo6aW50ZXJhY3RfcGxvdChzY3JfbW9kZWxzJHNjcjEuMSwgcHJlZCA9IGFyb3VzYWxfYywgbW9keCA9IHZhbGVuY2VfYywgbW9kMiA9IFRBU2MpCgoKCgpzY3JfbW9kZWxzJHNjcjI8LSBsbWVyKEJJT19DREEuSVNDUl9jb2xsYXBzZWQgfiAgYXJvdXNhbF9jKnZhbGVuY2VfYyAqVEFTYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCBzY3JfdXRsID09ICJub3RvdXRsaWVyIikpCgoKc3VtbWFyeShzY3JfbW9kZWxzJHNjcjIpCgoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHNjcl9tb2RlbHMkc2NyMiwgcHJlZCA9IGFyb3VzYWxfYywgbW9keCA9IHZhbGVuY2VfYykKCgpzY3JfbW9kZWxzJHNjcjI8LSBsbWVyKEJJT19DREEuU0NSX2NvbGxhcHNlZCB+ICBhcm91c2FsX2MqIHZhbGVuY2VfYyAqVEFTYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0LCBHcm91cCA9ICJOVCIpKQoKCnN1bW1hcnkoc2NyX21vZGVscyRzY3IyKQoKCmludGVyYWN0aW9uczo6aW50ZXJhY3RfcGxvdChzY3JfbW9kZWxzJHNjcjIsIHByZWQgPSBhcm91c2FsX2MsIG1vZHggPSB2YWxlbmNlX2MpCgojIHRoZSBlZmZlY3Qgb2YgcHVwaWwgaXMgdGhlIG9wcG9zaXRlIG9uIHNjcgoKCgpzY3JfbW9kZWxzJHNjcjM8LSBsbWVyKEJJT19DREEuSVNDUl9jb2xsYXBzZWQgfiAgYXJvdXNhbF9jICogdmFsZW5jZV9jICogVEFTYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfCBzc2lkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gIHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCBzY3JfdXRsID09ICJub3RvdXRsaWVyIikpCgoKc3VtbWFyeShzY3JfbW9kZWxzJHNjcjMpCgoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KHNjcl9tb2RlbHMkc2NyMiwgcHJlZCA9IGFyb3VzYWxfYywgbW9keCA9IHZhbGVuY2VfYywgbW9kMiA9IFRBU2MpCgojIHRoZSBlZmZlY3Qgb2YgcHVwaWwgaXMgdGhlIG9wcG9zaXRlIG9uIHNjcgoKCmBgYAoKCmNoZWNrIHNjciBvbiB3aXRoaW4gaW5kaXZpZHVhbHMKCmBgYHtyfQoKbG1fb2JqdGVzdDwtIGxtKEJJT19DREEuUGhhc2ljTWF4X3ogfiBhcm91c2FsICogdmFsZW5jZSwgZGF0YSA9IGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQpCmxtX29ianRlc3Rfc3VtbTwtc3VtbWFyeShsbV9vYmp0ZXN0KQpsbV9vYmp0ZXN0X3N1bW0kY29lZmZpY2llbnRzCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQKCmxtX29ianRlc3RbWyJjb2VmZmljaWVudHMiXV1bWzJdXQpsbV9vYmp0ZXN0W1siY29lZmZpY2llbnRzIl1dW1siYXJvdXNhbCJdXQpsbV9vYmp0ZXN0W1siY29lZmZpY2llbnRzIl1dW1sidmFsZW5jZSJdXQoKcmVncmVzc2lvbl9kZiA8LSBkYXRhLmZyYW1lKHNzaWQ9IHJlcChOQSwgNTApLCBFc3RpbWF0ZV9hcm91c2FsPSByZXAoTkEsIDUwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZV92YWxlbmNlPSByZXAoTkEsIDUwKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEVzdGltYXRlX2ludD0gcmVwKE5BLCA1MCksCiAgICAgICAgICAgICAgICAgICAgICAgICBwX2Fyb3VzYWw9IHJlcChOQSwgNTApLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHBfdmFsZW5jZT0gcmVwKE5BLCA1MCksCiAgICAgICAgICAgICAgICAgICAgICAgICBwX2ludD0gcmVwKE5BLCA1MCkpCgoKCmxtX2luZF9zdW1tYXJ5JGNvZWZmaWNpZW50c1tbMTRdXQoKc3NpZDwtIHVuaXF1ZShkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JHNzaWQpCgoKZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udDwtIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQlPiUKICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShhcm91c2FsX3pfc3NpZCA9IHNjYWxlKGFyb3VzYWwgLSBtZWFuKGFyb3VzYWwsIG5hLnJtID0gVFJVRSkpWywxXSwKICAgICAgICAgdmFsZW5jZV96X3NzaWQgPSBzY2FsZSh2YWxlbmNlIC0gbWVhbih2YWxlbmNlLCBuYS5ybSA9IFRSVUUpKVssMV0pCgppID0gMQoKcm0oYikKCiMgZGVidWcKc3NpZF90ZXM8LSB1bmlxdWUoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRzc2lkX251bSkKCnRhYmxlKGlzLm5hKGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQkQklPX0NEQS5QaGFzaWNNYXhfeikpCmxtX2luZCAgPC0gbG0oQklPX0NEQS5QaGFzaWNNYXhfeiB+IGFyb3VzYWxfel9zc2lkICp2YWxlbmNlX3pfc3NpZCwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwgIWlzLm5hKEJJT19DREEuUGhhc2ljTWF4X3opICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NpZF9udW0gPT0gc3NpZF90ZXNbMTBdKSkKCgpzdWJzZXQoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwgIWlzLm5hKEJJT19DREEuUGhhc2ljTWF4X3opICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NpZF9udW0gPT0gc3NpZF90ZXNbMTBdKQoKCgpgYGAKCgpgYGB7cn0KaSA9IDEKcm0oYikKCmZvciAoYiBpbiA1Omxlbmd0aChzc2lkX3RlcykpIHsKICAjIGZvciAocyBpbiAxOmxlbmd0aChuc2ltKSkgewoKICAgIG1lc3NhZ2Uoc3ByaW50ZigiJCQkJCRSVU5JTkcgbG1lciBmb3Igc3NpZCAlaSIsIHNzaWRfdGVzW2JdKSkKICAgICMgZGJfb2Y3X25ld19KRUZGRSRWaWRlb1R5cGVfY29udHJhc3Rfc2FtcGxlPC0gc2FtcGxlKChyZXAoYygtLjUsIC41KSwgZWFjaCA9ICAxOTIwKSksIHJlcGxhY2UgPSBGQUxTRSkgCiAgICAgICAgI3J1biB0aGUgbW9kZWwgb24gdGhlIGN1cnJlbnQgdGltZSBiaW4gYW5kIHNpbXVsYXRpb24gc3VtYmVyCiAgICAgICAgbG1faW5kICA8LSBsbShCSU9fQ0RBLlBoYXNpY01heF96IH4gYXJvdXNhbF96X3NzaWQgKnZhbGVuY2Vfel9zc2lkLAogICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCAhaXMubmEoQklPX0NEQS5QaGFzaWNNYXhfeikgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgPT0gIk1vcmUgbmVnYXRpdmUiJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NpZF9udW0gPT0gc3NpZF90ZXNbYl0pKQoKICAgICAgICAjc3RvcmUgcmVzdWx0cyBmcm9tIHRoZSBzaW11bGF0aW9uCiAgICAgICAgICAgIGxtX2luZF9zdW1tYXJ5PC0gc3VtbWFyeShsbV9pbmQpCiAgICAgICAgICAgIHJlZ3Jlc3Npb25fZGZbaSwxXTwtIHNzaWRfdGVzW2JdICNzYXZlIHNzaWQKICAgICAgICAgICAgcmVncmVzc2lvbl9kZltpLDJdPC0gbG1faW5kX3N1bW1hcnkkY29lZmZpY2llbnRzW1syXV0gIyBhcm91c2FsIGJldGEKICAgICAgICAgICAgcmVncmVzc2lvbl9kZltpLDNdPC1sbV9pbmRfc3VtbWFyeSRjb2VmZmljaWVudHNbWzNdXSAjIHZhbGVuY2UgYmV0YQogICAgICAgICAgICByZWdyZXNzaW9uX2RmW2ksNF08LWxtX2luZF9zdW1tYXJ5JGNvZWZmaWNpZW50c1tbNF1dICMgaW55dGVyYWN0aW9uIGJldGEKICAgICAgICAgICAgcmVncmVzc2lvbl9kZltpLDRdPC1sbV9pbmRfc3VtbWFyeSRjb2VmZmljaWVudHNbWzRdXSAKICAgICAgICAgICAgcmVncmVzc2lvbl9kZltpLDVdPC0gbG1faW5kX3N1bW1hcnkkY29lZmZpY2llbnRzW1sxNF1dCiAgICAgICAgICAgIHJlZ3Jlc3Npb25fZGZbaSw2XTwtIGxtX2luZF9zdW1tYXJ5JGNvZWZmaWNpZW50c1tbMTVdXQogICAgICAgICAgICByZWdyZXNzaW9uX2RmW2ksN108LSBsbV9pbmRfc3VtbWFyeSRjb2VmZmljaWVudHNbWzE2XV0KICAgICAgICAgICAgCiAgICAgICAgICAgIGxtX2luZF9zdW1tYXJ5JGNvZWZmaWNpZW50c1tbMTRdXQogICAgICAgICAgICAjIHNpbXVsYXRlZF9jbHVzdGVyc19KRUZGRVtpLDZdPC0gbnNpbVtzXSAjc3RvcmUgc2ltdWxhdGlvbiBvdW50CiAgICAgICAgICAgICMgdGltZWNvdXJzZV9yZXN1bHRfZGZfbmVnW2ksNV0gPC1pZmVsc2UobGVuZ3RoKGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UpCiAgICAgICAgICAgICMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIT0gMCwKICAgICAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxtZXJfYmluX3B1cF9zdW1tYXJ5JG9wdGluZm8kY29udiRsbWU0JG1lc3NhZ2UsICdwYXNzJykKCiAgICAgaSA9IGkrMQp9CgoKVmlldyhyZWdyZXNzaW9uX2RmKQoKIGxtX2luZF9zdW1tYXJ5JGNvZWZmaWNpZW50c1tbNF1dCiMgd2hldGhlciBJIHVzZSBncm91bmQgdmFsZW5jZSwgc2VsZiB2YWxlbWNlIG9yIHRoaXMgc2FtcGxlIGF2ZXJhZ2UgdmFsZW5jZSwgSSBnZXQgdGhlIHNhbWUgcGF0dGVybnMKCnRpbWVjb3Vyc2VfcmVzdWx0X2RmX25lZyU+JQogIGdncGxvdChhZXModGltZWJpbnMsIHQpKSsKICBnZW9tX2xpbmUoc2l6ZSA9IDIpKwogIGdlb21fbGluZShhZXMoeSA9IHApLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjEsIGNvbG9yID0gJ3JlZCcsIHNpemUgPSAxLjUpCgoKdC50ZXN0KHJlZ3Jlc3Npb25fZGYkRXN0aW1hdGVfYXJvdXNhbCkKCnNzaWQjIGp1c3QgcG9zaXRpdmUKcmVncmVzc2lvbl9kZiA8LSBkYXRhLmZyYW1lKHNzaWQ9IHJlcChOQSwgNTApLCBFc3RpbWF0ZV9hcm91c2FsPSByZXAoTkEsIDUwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBFc3RpbWF0ZV92YWxlbmNlPSByZXAoTkEsIDUwKSwKICAgICAgICAgICAgICAgICAgICAgICAgIEVzdGltYXRlX2ludD0gcmVwKE5BLCA1MCksCiAgICAgICAgICAgICAgICAgICAgICAgICBwX2Fyb3VzYWw9IHJlcChOQSwgNTApLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHBfdmFsZW5jZT0gcmVwKE5BLCA1MCksCiAgICAgICAgICAgICAgICAgICAgICAgICBwX2ludD0gcmVwKE5BLCA1MCkpCgoKYGBgCgoKCgoKCgoKCmBgYHtyfQoKc2NhdHRlcjNEKHgsIHksIHosIGNsYWIgPSBjKCJTZXBhbCIsICJXaWR0aCAoY20pIikpCgpkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250CgppbnN0YWxsLnBhY2thZ2VzKCJwbG90M0QiKQppbnN0YWxsLnBhY2thZ2VzKCJtaXNjM2QiKQpsaWJyYXJ5KG1pc2MpCgpwbG90M0Q6OnNjYXR0ZXIzRChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JHB1cF9iYXNDb3IsIAogICAgICAgICAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRhcm91c2FsX2MsIAogICAgICAgICAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCR2YWxlbmNlX2MpCgogaW5zdGFsbC5wYWNrYWdlcygicGxvdDNEIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKIAogIGluc3RhbGwucGFja2FnZXMoIm1pc2MzZCIsIHJlcG8gPSAnaHR0cHM6Ly9tYWMuUi1wcm9qZWN0Lm9yZycpCiAKIAppbnN0YWxsLnBhY2thZ2VzKGMoInJnbCIsICJjYXIiKSkKCmxpYnJhcnkoY2FyKQoKaW5zdGFsbC5wYWNrYWdlcygiY2FyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKCgpjYXI6OnNjYXR0ZXIzZChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JGFyb3VzYWxfYywgCiAgICAgICAgICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JHB1cF9iYXNDb3IsIAogICAgICAgICAgZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCR2YWxlbmNlX2MsCiAgICAgICAgICBmaXQgPSAic21vb3RoIgogICAgICAgICAgIyBwb2ludCA9IEZBTFNFLAogICAgICAgICAgCiAgICAgICAgICAjIHN1cmZhY2UgPSBGQUxTRSwKICAgICAgICAgICMgcG9pbnQuY29sID0gIiIKICAgICAgICAgICkKCgpgYGAKCgoKZ2cgPSBnZ3Bsb3QoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCwgYWVzKEJJT19DREEuUGhhc2ljTWF4X3osIGFyb3VzYWxfYykpICsKICBzdGF0X2RlbnNpdHlfMmQoYWVzKGZpbGwgPSBzdGF0KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQkdmFsZW5jZV9jKSksIAogICAgICAgICAgICAgICAgICBnZW9tID0gInBvbHlnb24iLAogICAgICAgICAgICAgICAgICBuID0gMTAwLGJpbnMgPSAxMCxjb250b3VyID0gVFJVRSkgKwogICMgZmFjZXRfd3JhcChjbGFyaXR5fi4pICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiQSIpCgpyYXlzaGFkZXI6OnBsb3RfZ2coZ2csbXVsdGljb3JlPVRSVUUsd2lkdGg9NSxoZWlnaHQ9NSxzY2FsZT0yNTApCgpzY3I8LSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JEJJT19DREEuUGhhc2ljTWF4X3oKYXJvdXNhbDwtIGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQkYXJvdXNhbF9jCgp2YWxlbmNlID0gZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCR2YWxlbmNlX2MKCgoKCmdnID0gZ2dwbG90KGRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3RfbnQsIGFlcyhCSU9fQ0RBLlBoYXNpY01heF96LCBhcm91c2FsX2MpKSArCiAgc3RhdF9kZW5zaXR5XzJkKGFlcyhmaWxsID0gc3RhdCh2YWxlbmNlX2MpKSwgCiAgICAgICAgICAgICAgICAgIGdlb20gPSAicG9seWdvbiIsCiAgICAgICAgICAgICAgICAgICMgbiA9IDEwMCxiaW5zID0gMTAsCiAgICAgICAgICAgICAgICAgIGNvbnRvdXIgPSBUUlVFKSArCiAgIyBmYWNldF93cmFwKGNsYXJpdHl+LikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJBIikKcmF5c2hhZGVyOjpwbG90X2dnKGdnLG11bHRpY29yZT1UUlVFLHdpZHRoPTUsaGVpZ2h0PTUsc2NhbGU9MjUwKQpnZwojTm8gbGluZXMKcHBfbm9saW5lcyA9IGdncGxvdChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCBhZXMoeD1CSU9fQ0RBLlBoYXNpY01heF96LCB5PWFyb3VzYWxfYykpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHZhbGVuY2VfYykpCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoYSkKCnJheXNoYWRlcjo6cGxvdF9nZyhwcF9ub2xpbmVzLCB3aWR0aCA9IDQsIGhlaWdodCA9IDQsIHNjYWxlID0gMzAwLCBtdWx0aWNvcmUgPSBUUlVFKQpwcF9ub2xpbmVzCgoKP3NjYXR0ZXIzZApzY2F0dGVyM2QoeCA9IGFyb3VzYWwsIAogICAgICAgICAgeSA9IHZhbGVuY2UsIHogPSBzY3IsIAogICAgICAgICAgZml0ID0gInNtb290aCIsCiAgICAgICAgICAKICAgICAgICAgICMgc3VyZmFjZSA9IEZBTFNFLAogICAgICAgICAgcG9pbnQuY29sID0gImJsdWUiLCAKICAgICAgICAgICMgcG9pbnQKICAgICAgICAgIGdyb3VwcyA9IGFzLmZhY3RvcihkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiksIAogICAgICAgICAgZWxsaXBzb2lkID0gRkFMU0UpCgoKCnNjYXR0ZXIzZCh4ID0gZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRwdXBfYmFzQ29yLCAKICAgICAgICAgIHkgPSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250JEJJT19DREEuUGhhc2ljTWF4X3osIHogPSBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250LCAKICAgICAgICAgIGZpdCA9ICJzbW9vdGgiLAogICAgICAgICAgCiAgICAgICAgICAjIHN1cmZhY2UgPSBGQUxTRSwKICAgICAgICAgIHBvaW50LmNvbCA9ICJibHVlIiwgCiAgICAgICAgICAjIHBvaW50CiAgICAgICAgICBncm91cHMgPSBhcy5mYWN0b3IoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdF9udCRtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSksIAogICAgICAgICAgZWxsaXBzb2lkID0gRkFMU0UpCgoKbGlicmFyeSh2aXJpZGlzTGl0ZSkKaW5zdGFsbC5wYWNrYWdlcygidmlyaWRpcyIpCmxpYnJhcnkodmlyaWRpcykKZGVhdGhnZyA9IGdncGxvdChkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0X250KSArCiAgZ2VvbV90aWxlKGFlcyh4PWFyb3VzYWxfYyx5PXB1cF9iYXNDb3IsZmlsbD12YWxlbmNlX2MpKSsKICAjIHNjYWxlX3hfY29udGludW91cygiWWVhciIsZXhwYW5kPWMoMCwwKSxicmVha3M9c2VxKDE5MDAsMjAxMCwxMCkpICsKICAjIHNjYWxlX3lfY29udGludW91cygiQWdlIixleHBhbmQ9YygwLDApLGJyZWFrcz1zZXEoMCwxMDAsMTApLGxpbWl0cz1jKDAsMTAwKSkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpcygpCiAgIyBnZ3RpdGxlKCJEZWF0aCBQcm9iYWJpbGl0eSB2cyBBZ2UgYW5kIFllYXIgZm9yIHRoZSBVU0EiKSArCiAgIyBsYWJzKGNhcHRpb24gPSAiRGF0YSBTb3VyY2U6IFVTIERlcHQuIG9mIFNvY2lhbCBTZWN1cml0eSIpCiAgCnJheXNoYWRlcjo6IHBsb3RfZ2coZGVhdGhnZywgbXVsdGljb3JlPVRSVUUpCmhlaWdodD01LHdpZHRoPTYsc2NhbGU9NTAwCgpgYGAKCmhlYXJ0IHJhdGUKCgpgYGB7cn0KCgoKCgp1bmlxdWUoZGJfZnVsbDZuZXckQmlvX01lYW5fSFIpCnVuaXF1ZShkYl9mdWxsNm5ldyRCaW9fTWVhbl9IUl9maXgpCgoKVmlldyhkYl9mdWxsNm5ldykKCmRiX2Z1bGw0bmV3X3N0aW1fc2NyZWVuX3B1cGlsX25vcHJhY3QKICBkYl9mdWxsNG5ld19zdGltX3NjcmVlbl9wdXBpbF9ub3ByYWN0ICU+JQogICMgc3Vic2V0KHNzaWQgPT0gMzE0KSU+JQogICAgZ3JvdXBfYnkoc3NpZCklPiUKICAgIG11dGF0ZShCSU9fQ0RBLlNDUl96ID0gc2NhbGUobG9nMXAoQklPX0NEQS5QaGFzaWNNYXggKy4xKSlbLDFdKSU+JQogICAgbXV0YXRlKGFyb3VzYWxfeiA9IHNjYWxlKGFyb3VzYWwgKy4xKSklPiUKICBnZ3Bsb3QoYWVzKGFyb3VzYWxfeixCSU9fQ0RBLlNDUl96LCBjb2xvciA9bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgLCBzaGFwZSA9bWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwpKSsKICAgIGdlb21fcG9pbnQoKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgICBmYWNldF93cmFwKH5zc2lkKSsKICAgIGdncHVicjo6c3RhdF9jb3IoKQoKCmBgYAoKCmBgYAoKYGBge3J9CgojIGtlZXAgc3RpbSBhbmQgYW5kIGZpeGF0aW9uCgp1bmlxdWUoZGJfZnVsbDZuZXckc2NyZWVuY29udGVudCkKdW5pcXVlKGRiX2Z1bGw2bmV3JHNjcmVlbmNvbnRlbnRfbm8pCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltPC0gc3Vic2V0KGRiX2Z1bGw2bmV3LCBzY3JlZW5jb250ZW50X25vIDwzKQpWaWV3KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltKQojIGZpeGF0aW9uIiAgICAic3RpbSIgCgojIGtlZXAgY29udHJvbHMKdW5pcXVlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltJHNzaWQpCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltJHNzaWRfbnVtIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltJHNzaWQpKQoKCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDwtIHN1YnNldChkYl9mdWxsNm5ld19ocl9maXhfc3RpbSwgR3JvdXAgPT0gIk5UIikKdW5pcXVlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250JHNzaWRfbnVtKQoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQ8LSBzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW0sIHNzaWRfbnVtPiAzMDMpCnVuaXF1ZShkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udCRzc2lkKQoKIyBIUiBkaWZmZXJlbmNlcwpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udCRCaW9fTWVhbl9IUl9maXg8LSBpZl9lbHNlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250JHNjcmVlbmNvbnRlbnRfbm8gPT0xLCBkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udCRCaW9fTWVhbl9IUiwgTlVMTCkKClZpZXcoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQpCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxPC0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQgJT4lCiAgZ3JvdXBfYnkoc3NpZCwgdE5vKSAlPiUKICBhcnJhbmdlKHNzaWQsIHRObyxzY3JlZW5jb250ZW50X25vKSU+JQogIGZpbGwoQmlvX01lYW5fSFJfZml4LCAuZGlyZWN0aW9uID0gImRvd24iKSU+JQogIHN1YnNldChzY3JlZW5jb250ZW50X25vID09IDIpCgpWaWV3KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSkKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MTwtIGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSAlPiUKICBtdXRhdGUoQmlvX01lYW5fSFJfZGlmID0gQmlvX01lYW5fSFIgLSBCaW9fTWVhbl9IUl9maXgpCiMgMiAxCnN0aW0gLSBmaXgKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ2dwbG90KGFlcyhCaW9fTWVhbl9IUl9kaWYpKSsKICBnZW9tX2hpc3RvZ3JhbSgpCgo/c2NhdHRlcjNkIAoKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSU+JQogIHN1YnNldCghaXMubmEocHVwX2Jhc0NvcikpJT4lCiAgIHN1YnNldCghaXMubmEoQklPX0NEQS5QaGFzaWNNYXhfeikpJT4lCiAgc3Vic2V0KCFpcy5uYShCaW9fTWVhbl9IUl9kaWYpKQoKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MTwtIGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKEJJT19DREEuUGhhc2ljTWF4X3o9IHNjYWxlKEJJT19DREEuUGhhc2ljTWF4LCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IFRSVUUpWywxXSkKCnNjYXR0ZXIzZCh4ID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJHB1cF9iYXNDb3IsIAogICAgICAgICAgeSA9IGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCSU9fQ0RBLlBoYXNpY01heF96LCAKICAgICAgICAgIHogPSBkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEkQmlvX01lYW5fSFJfZGlmLCAKICAgICAgICAgIGZpdCA9ICJzbW9vdGgiLAogICAgICAgICAgCiAgICAgICAgICBzdXJmYWNlID0gRkFMU0UsCiAgICAgICAgICBwb2ludC5jb2wgPSAiYmx1ZSIsCiAgICAgICAgICAjIHBvaW50CiAgICAgICAgICBncm91cHMgPSBhcy5mYWN0b3IoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsKSwKICAgICAgICAgIGVsbGlwc29pZCA9IFRSVUUpCgoKCmNvcihkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDFbLGMoInB1cF9iYXNDb3IiLCAiQklPX0NEQS5QaGFzaWNNYXhfeiIsIkJpb19NZWFuX0hSX2RpZiIpXSwgdXNlID0gImNvbXBsZXRlIikKCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ3JvdXBfYnkoc3NpZCxtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMocHVwX2Jhc0NvcixCSU9fQ0RBLlBoYXNpY01heF96LCBjb2xvcj0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICB5bGltKDAsLjQpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiUKICAjIGdyb3VwX2J5KHNzaWQpJT4lCiAgIyBtdXRhdGUoQmlvX01lYW5fSFJfZGlmX3ogPSBzY2FsZShCaW9fTWVhbl9IUl9kaWYpKQogIGdyb3VwX2J5KHNzaWQsbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKHB1cF9iYXNDb3IsQmlvX01lYW5fSFJfZGlmX3osIGNvbG9yPSBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICMgeWxpbSgtNywyKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpJT4lCiAgIyBncm91cF9ieShzc2lkKSU+JQogICMgbXV0YXRlKEJpb19NZWFuX0hSX2RpZl96ID0gc2NhbGUoQmlvX01lYW5fSFJfZGlmKSkKICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhCSU9fQ0RBLlBoYXNpY01heF96LEJpb19NZWFuX0hSX2RpZiwgY29sb3I9IG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgIyB5bGltKC03LDIpKwogIGdncHVicjo6c3RhdF9jb3IoKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkKICAKCmBgYAoKCmBgYHtyfQoKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWZfb3V0bDwtIGlmX2Vsc2UoYWJzKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWYpPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1lZGlhbihhYnMoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJEJpb19NZWFuX0hSX2RpZiksbmEucm0gPSBUUlVFKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoNCooc2QoYWJzKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWYpLCBuYS5ybSA9IFRSVUUpKSkpLCAib3V0bGllciIsICJub3Qgb3V0bGllciIpCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ2dwbG90KGFlcyhCaW9fTWVhbl9IUl9kaWYpKSsKICBnZW9tX2hpc3RvZ3JhbSgpKwogIGZhY2V0X2dyaWQofkJpb19NZWFuX0hSX2RpZl9vdXRsKQoKYGBgCgoKYGBge3J9CmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSAlPiUKICAgIHN1YnNldChCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiKSU+JQogIHN1YnNldChzc2lkX251bTw1MDApJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBtdXRhdGUoQmlvX01lYW5fSFJfZGlmX3NzaWQgPSBtZWFuKEJpb19NZWFuX0hSX2RpZiwgbmEucm0gPSBUUlVFKSklPiUKICBncm91cF9ieShzc2lkKSU+JQogICMgbXV0YXRlKEJpb19NZWFuX0hSX2RpZl9zdGltID0gbWVhbihCaW9fTWVhbl9IUl9kaWYsIG5hLnJtID0gVFJVRSkpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKFRBU2MsIEJpb19NZWFuX0hSX2RpZikpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKQogIAogIAoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxICU+JQogICAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIpJT4lCiAgc3Vic2V0KHNzaWRfbnVtPDUwMCklPiUKICAjIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKEJpb19NZWFuX0hSX2RpZiA9IGFicyhCaW9fTWVhbl9IUl9kaWYpKSU+JQogIGdyb3VwX2J5KHNzaWQsIHN0aW1JQVBTKSU+JQogIG11dGF0ZShCaW9fTWVhbl9IUl9kaWZfc3RpbSA9IGFicyhCaW9fTWVhbl9IUl9kaWYpKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhUQVNjLCBCaW9fTWVhbl9IUl9kaWYpKSsKICAjIGdlb21fcG9pbnQoKQogIAogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHN0aW1JQVBTLCB5ID1CaW9fTWVhbl9IUl9kaWZfc3RpbSksIG1ldGhvZD1sbSwgc2U9RkFMU0UsIGNvbG91ciA9ICJncmF5NDAiLCBhbHBoYSA9IC4wMSxsaW5ldHlwZT0iZGFzaGVkIiwgc2l6ZSA9IC4yICkrCiAgZ2VvbV9zbW9vdGgoIG1ldGhvZD1sbSwgc2U9RkFMU0UsIGxpbmV0eXBlPSJkYXNoZWQiLAogICAgICAgICAgICAgY29sb3I9ImRhcmtyZWQiLCBzaXplID0gMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScsIHBjaCA9IDEpKwogIAogIAogIAogICMgZ2VvbV9wb2ludCgpKwogICMgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9c3NpZCwgeSA9IEJpb19NZWFuX0hSX2RpZiksbWV0aG9kID0gImxpbmUiLGFscGhhID0gLjEpKwogICMgZ2dwdWJyOjpzdGF0X2NvcigpKwogIHAkZ3JhcGhzdHlsZSsKICB4bGFiKCJBbGV4aXRoeW1pYSAoWikiKSsKICB5bGFiKCJIUiBkaWZmZXJlbmNlIikrCnAkZ3JhcGhzdHlsZQoKCgpocl9iaW8gPC0gbG1lcihCaW9fTWVhbl9IUl9kaWYgfiBUQVNjICphcm91c2FsX2MgKyAoMXxzc2lkKSArICgxfCBzdGltSUFQUyksCiAgICAgUkVNTCA9IEZBTFNFLAogICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxLCBCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiKSkKCgppbnRlcmFjdGlvbnM6OmludGVyYWN0X3Bsb3QoaHJfYmlvLCBwcmVkID0gYXJvdXNhbF9jLCBtb2R4ID0gVEFTYykKCgpzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxLCBCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiKQoKCmBgYAoKYGBge3J9CmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSAlPiUKICBzdWJzZXQoQmlvX01lYW5fSFJfZGlmX291dGwgPT0gIm5vdCBvdXRsaWVyIiklPiUKICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShjb3JfaHJkaWZfYXIgPSBjb3IoQmlvX01lYW5fSFJfZGlmLCBhcm91c2FsX2MpKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhUQVMsIGNvcl9ocmRpZl9hcikpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKSsKICBwJGdyYXBoc3R5bGUKCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxICU+JQogIHN1YnNldChUQVM8NzApJT4lCiAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIpJT4lCiAgZ3JvdXBfYnkoc3NpZCxtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSklPiUKICBtdXRhdGUoY29yX2hyZGlmX2FyID0gY29yKEJpb19NZWFuX0hSX2RpZiwgYXJvdXNhbF9jKSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIGNvcl9ocmRpZl9hcikpKwogIGdlb21faml0dGVyKGFscGhhID0gLjEsIHdpZHRoID0gLjEpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpKwogIHAkZ3JhcGhzdHlsZQogIApgYGAKCgoKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSAlPiUKICAjIHN1YnNldChCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiKSU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKGNvcl9ocmRpZl9hciA9IGNvcihCaW9fTWVhbl9IUl9kaWYsIGFyb3VzYWxfYykpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKFRBUywgY29yX2hyZGlmX2FyKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgpgYGB7cn0KZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxPC0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMpJT4lCiAgbXV0YXRlKFZhbGVuY2VNZWFuVGhpc1NhbXBsZSA9IG1lYW4odmFsZW5jZSwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgIEFyb3VzYWxNZWFuVGhpc1NhbXBsZSA9IG1lYW4oYXJvdXNhbCwgbmEucm0gPSBUUlVFKSkKCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDE8LSBkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiUKICB1bmdyb3VwKCklPiUKICBtdXRhdGUobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgPSBpZl9lbHNlKFZhbGVuY2VNZWFuID49CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuKFZhbGVuY2VNZWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLCAiTW9yZSBwb3NpdGl2ZSIsICJNb3JlIG5lZ2F0aXZlIikpJT4lCiAgbXV0YXRlKG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsID0gaWZfZWxzZShBcm91c2FsTWVhbiA+PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbihBcm91c2FsTWVhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKSwgIkhpZ2giLCAiTG93IikpJT4lCiAgICBtdXRhdGUobWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyID0gaWZfZWxzZShWYWxlbmNlTWVhblRoaXNTYW1wbGUgPj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW4oVmFsZW5jZU1lYW5UaGlzU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYS5ybSA9IFRSVUUpLCAiTW9yZSBwb3NpdGl2ZSIsICJNb3JlIG5lZ2F0aXZlIikpJT4lCiAgbXV0YXRlKG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiA9IGlmX2Vsc2UoQXJvdXNhbE1lYW5UaGlzU2FtcGxlID49CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFuKEFyb3VzYWxNZWFuVGhpc1NhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUUlVFKSwgIkhpZ2giLCAiTG93IikpCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIpJT4lCiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpJT4lCiAgZ3JvdXBfYnkoc3NpZCxtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgQmlvX01lYW5fSFJfZGlmKSkrCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuMiwgd2lkdGggPSAuMikrCiAgIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpKwogICMgc3RhdF9zbW9vdGgoYWVzKGdyb3VwID0gc3NpZCksIHNlID0gRiwgbWV0aG9kID0gJ2xtJywgYWxwaGEgPSAuMikrCiAgICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkKICAKYGBgCgpgYGB7cn0gIApkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSklPiUKICBzdWJzZXQoQmlvX01lYW5fSFJfZGlmX291dGw9PSAibm90IG91dGxpZXIiKSU+JQogIGdyb3VwX2J5KHNzaWQsIG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCwgQmlvX01lYW5fSFJfZGlmLCBmaWxsID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSsKICBnZW9tX2ppdHRlcihhbHBoYSA9IC4yLCB3aWR0aCA9IC4yKSsKICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC4yKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgc3RhdF9zdW1tYXJ5KGFlcyhncm91cCA9IHNzaWQpLCBnZW9tID0gJ2xpbmUnLCBhbHBoYSA9IC4yKSsKICAKIAogIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucygpCiAgIyBwJGdyYXBoc3R5bGUrCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpKwoKCmBgYAogICMgc3RhdF9zbW9vdGgoYWVzKGdyb3VwID0gc3NpZCksIHNlID0gRiwgbWV0aG9kID0gJ2xtJywgYWxwaGEgPSAuMikKCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSklPiUKICBzdWJzZXQoQmlvX01lYW5fSFJfZGlmX291dGwhPSAib3V0bGllciIpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfZ3JvdW5kX2Fyb3VzYWwsbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsLCBCaW9fTWVhbl9IUl9kaWYpKSsKICBnZW9tX2ppdHRlcihhbHBoYSA9IC4yLCB3aWR0aCA9IC4yKSsKICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC4yKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkKCgojIHNlbGYgCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDElPiUKICBzdWJzZXQoIWlzLm5hKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSklPiUKICBzdWJzZXQoQmlvX01lYW5fSFJfZGlmX291dGwhPSAib3V0bGllciIpJT4lCiAgZ3JvdXBfYnkoc3NpZCwgbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBCaW9fTWVhbl9IUl9kaWYpKSsKICBnZW9tX2ppdHRlcihhbHBoYSA9IC4yLCB3aWR0aCA9IC4yKSsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEsIHNpemUgPSAuNCwgY29sb3VyID0gIkJsYWNrIikgKwogICAjIGdlb21fYmFyKHN0YXQ9InN1bW1hcnkiLCBmdW4ueSA9ICJtZWFuIiwgYWxwaGEgPSAuMikrCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpKwogIGdncHVicjo6c3RhdF9jb21wYXJlX21lYW5zKCkrCiAgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKQoKCgpsbWVyKAogIGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSkKCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbCkpKwogIGdlb21faGlzdG9ncmFtKCkKCmBgYHtyfQojIHRlc3QgLSBhbmFseXNlIGp1c3QgcG9zaXRpdmUKaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCA8LSBsbWVyKEJpb19NZWFuX0hSX2RpZiB+ICB2YWxlbmNlX2MgKmFyb3VzYWxfYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKDEgfCBzc2lkKSArICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDF8bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSwKICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlID09ICJNb3JlIHBvc2l0aXZlIiAmIEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIgICYgR3JvdXAgPT0gIk5UIikpCgoKc3VtbWFyeShocl9kaWZfbW9kZWxzJGFyb3VzYWxfdmFsKQoKCnVuaXF1ZShkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEkc3NpZCkKaHJfZGlmX21vZGVscyR2YWxmcm9tX2hyIDwtIGxtZXIodmFsZW5jZV9jIH4gICBCaW9fTWVhbl9IUl9kaWYqIGFyb3VzYWxfYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKDEgfCBzc2lkKSArICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDF8bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSwKICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlID09ICJNb3JlIHBvc2l0aXZlIiAmCiAgICAgICAgICAgICAgICAgICBCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiICYgR3JvdXAgPT0gIk5UIikpCmFyb3VzYWxfYwoKCnN1bW1hcnkoaHJfZGlmX21vZGVscyR2YWxmcm9tX2hyKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KGhyX2RpZl9tb2RlbHMkdmFsZnJvbV9ociwgcHJlZCA9IEJpb19NZWFuX0hSX2RpZiwgbW9keCA9IGFyb3VzYWxfYykKCnBsb3QoaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCkKCmNhcjo6dmlmKGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWwpCiAjIHZhbGVuY2VfYyAgICAgICAgICAgYXJvdXNhbF9jIHZhbGVuY2VfYzphcm91c2FsX2MgCiAgICAgICAgICAgIyAxLjc2NzYwNSAgICAgICAgICAgIDEuNzA4NjQyICAgICAgICAgICAgMS4wNzA2MzUKCj9zdGVwCj9sbWVyVGVzdDo6c3RlcCgpCmxtZXJUZXN0OjpzdGVwKGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWwpCgojIGZhdm91cnMgdmFsZW5jZQoKIyBjaGVjayB0aGUgcmVzcG9uc2UgYmlhcyB0aGluZwpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEgJT4lCiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpJT4lCiAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIpJT4lCiAgZ2dwbG90KGFlcyhsb2cxMChhcm91c2FsKzEwLjUpICxCaW9fTWVhbl9IUl9kaWYpKSsKICAgICMgZ2VvbV9wb2ludChhbHBoYSA9IC4xKSsKICAgIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdnc2lkZTo6Z2VvbV95c2lkZWRlbnNpdHkoYWVzKHg9c3RhdChkZW5zaXR5LCBmaWxsID0gbWVkaWFuc3BsaXRfc2VsZl92YWxlbmNlKSwgYWxwaGEgPSAuNCkpKwpnZ3NpZGU6Omdlb21feHNpZGVkZW5zaXR5KGFlcyh5PXN0YXQoZGVuc2l0eSwgZmlsbCA9IG1lZGlhbnNwbGl0X3NlbGZfdmFsZW5jZSksIGFscGhhID0gLjQpKQoKCgpzY2F0dGVyM2QoeCA9IGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSR2YWxlbmNlX2MsIAogICAgICAgICAgeSA9ZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJEJpb19NZWFuX0hSX2RpZiwgeiA9ZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJGFyb3VzYWxfYywKICAgICAgICAgICMgZml0ID0gInNtb290aCIsCiAgICAgICAgICAKICAgICAgICAgICMgc3VyZmFjZSA9IEZBTFNFLAogICAgICAgICAgcG9pbnQuY29sID0gImJsdWUiLCAKICAgICAgICAgICMgcG9pbnQKICAgICAgICAgICMgZWxsaXBzb2lkID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJG1lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMikKICAgICAgICAgIGVsbGlwc29pZCA9IFRSVUUpCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBtZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBWYWxlbmNlTWVhbikpKwogIGdlb21fcG9pbnQoKQoKCgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgc3Vic2V0KENvbmRpdGlvbiA9PSAiSUFQUyIpJT4lCiAgZ3JvdXBfYnkoc3RpbUlBUFMsIG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSwgYXJvdXNhbCkpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucygpKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzdGltSUFQUykpCgpgYGAKCgoKCgpjaGVjayBjb3JlbGF0aW9uIGJldHdlZW4gYXJvdXNhbCBhbmQgdmFsZW5jZSBvbiBhbmQgaW5kaXZpZHVhbCBiYXNpcwoKCmBgYHtyfQoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJGFyb3VzYWxfYwpzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxLCBtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSA9PSAiTW9yZSBwb3NpdGl2ZSIgJiBCaW9fTWVhbl9IUl9kaWZfb3V0bCA9PSAibm90IG91dGxpZXIiKSAlPiUKICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShjb3JfdmFsZV9hciA9IGNvcihhcm91c2FsLCB2YWxlbmNlLCB1c2UgID0gImNvbXBsZXRlIikpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGNvcl92YWxlX2FyKSkrCiAgICBnZW9tX2hpc3RvZ3JhbSgpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IC0uNykKCgoKc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBzdGltSUFQUyklPiUKICAjIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyggdmFsZW5jZSwgYXJvdXNhbCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gc3NpZCksIHNlICA9IEYsIG1ldGhvZCA9ICdsbScpKwogICMgZmFjZXRfZ3JpZCh+bWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCgpzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxKSU+JQogIHN1YnNldChzc2lkID09IDMzMSklPiUKICAjIGdyb3VwX2J5KG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlLCBzdGltSUFQUyklPiUKICAjIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyggYXMubnVtZXJpYyh0Tm8pLCBhcm91c2FsKSkrCiAgZ2VvbV9wb2ludCgpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gImxpbmUiKSsKICBnZW9tX3BvaW50KGFlcyh5ID0gdmFsZW5jZSksIGNvbG9yID0gImdyZWVuIikrCiAgc3RhdF9zdW1tYXJ5KGFlcyh5ID0gdmFsZW5jZSksZ2VvbSA9ICJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZ3JlZW4iKQogICMgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHNzaWQpLCBzZSAgPSBGLCBtZXRob2QgPSAnbG0nKSsKICAjIGZhY2V0X2dyaWQofm1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSsKICAjIGdncHVicjo6c3RhdF9jb3IoKQogIAoKCgoKCmBgYAoKCgojIHRyeSBhbmQgcmVncmVzcyB2YWxlbmNlIG91ciBvYXJvdXNhbF92YWwKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MgoKZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQzPC0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MiwgIWlzLm5hKHZhbGVuY2UpKQoKaHJfZGlmX21vZGVscyRhcm9zYWxfZnJvbV92YWwgPC0gbG1lcihhcm91c2FsX2N+ICB2YWxlbmNlX2MgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoMSB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAoMXxtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpLAogICAgIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MykpCgoKaHJfZGlmX21vZGVscyR2YWxfZnJvbV9hcm91c2FsIDwtIGxtZXIodmFsZW5jZV9jfmFyb3VzYWxfYysKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKDEgfCBzc2lkKSArICgxfHN0aW1JQVBTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgKDF8bWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKSwKICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IHN1YnNldChkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDMpKQoKCmhyX2RpZl9tb2RlbHMkYXJvc2FsX2Zyb21fdmFsCnBsb3QoaHJfZGlmX21vZGVscyRhcm9zYWxfZnJvbV92YWwpCgo/cmVzaWR1YWxzCj9yZXNpZAo/cmVzaWR1YWxzLm1lck1vZApkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDMkYXJvdXNfdmFsX3Jlc2lkIDwtIHJlc2lkdWFscyhocl9kaWZfbW9kZWxzJGFyb3NhbF9mcm9tX3ZhbCkKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MyR2YWxfZnJvbV9hcm91c19yZXNpZDwtIHJlc2lkdWFscyhocl9kaWZfbW9kZWxzJHZhbF9mcm9tX2Fyb3VzYWwpCgojIHJlc2lkdWFscy5tZXJNb2QoaHJfZGlmX21vZGVscyRhcm9zYWxfZnJvbV92YWwpCgphcl9mcm1fdmFsPC0gbG0oYXJvdXNhbF9jIH4gdmFsZW5jZV9jLCBkYXRhID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQzKQoKdmFsX2ZybV92YWw8LSBsbSggdmFsZW5jZV9jfmFyb3VzYWxfYywgZGF0YSA9IGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MykKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MyU+JWdncGxvdChhZXModmFsX2Zyb21fYXJvdXNfcmVzaWQsIGFyb3VzX3ZhbF9yZXNpZCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCmBgYAoKCnJlc2lkKGFyX2ZybV92YWwpCnJlc2lkKHZhbF9mcm1fdmFsKQogIyAgICAgICAgICAgMSAgICAgICAgICAgIDIgICAgICAgICAgICAzICAgICAgICAgICAgNCAgICAgICAgICAgIDUgICAgICAgICAgICA2ICAgICAgICAgICAgNyAgICAgICAgICAgIDggCiAjIDAuMTQ5OTYyODQzICAwLjUwNTgxNTUwNwogIyAKICMgLTAuNjM3NTEyOTU4ICAwLjA0NDU4MDYwMiAKIAogCiAKSXMgdGhlIHJlc2lkdWFsIG9mIEF+IEIgdGhlIHNhbWUgYXMgQn5BIApgYGB7cn0KCmhyX2RpZl9tb2RlbHMkdmFsX2Zyb21fYXJvdXNhbCA8LSBsbWVyKHZhbGVuY2VfY35hcm91c2FsX2MrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICgxIHwgc3NpZCkgKyAoMXxzdGltSUFQUyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICgxfG1lZGlhbnNwbGl0X3NhbXBsZV9hcm91c2FsMiksCiAgICAgUkVNTCA9IEZBTFNFLAogICAgIGRhdGEgPSBzdWJzZXQoZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQzKSkKCgpocl9kaWZfbW9kZWxzJGJpb2hyX2RpZl9hcm91c19yZXMgPC0gbG1lcihCaW9fTWVhbl9IUl9kaWZ+ICB2YWxfZnJvbV9hcm91c19yZXNpZCAqYXJvdXNfdmFsX3Jlc2lkKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoMSB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAoMXxtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpLAogICAgIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gc3Vic2V0KGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MywgQmlvX01lYW5fSFJfZGlmX291dGwgPT0gIm5vdCBvdXRsaWVyIikpCgoKc3VtbWFyeShocl9kaWZfbW9kZWxzJGJpb2hyX2RpZl9hcm91c19yZXMpCgojIGFuYWx5c2VzIG9mIHJlc2lkdWFscyBhbHNvIHN1Z2dldHMgdGhhdCBlZmZlY3RzIG9uIGJpb19ociBhcmUgcmVsYXRlZCB0byBjb21tb24gYXJvdXNhbCBhbmQgdmFsZW5jZSByZWxhdGlvbgoKYGBgCgppbnRlcmFjdGlvbnM6OmludGVyYWN0X3Bsb3QoaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCwgcHJlZD0gYXJvdXNhbF9jLCBtb2R4ID0gdmFsZW5jZV9jKQoKCiMgYWxleGl0aGp5bWlhCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWZfejwtIHNjYWxlKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSRCaW9fTWVhbl9IUl9kaWYsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gVFJVRSlbLDFdCmhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWxfY2F0IDwtIGxtZXIoQmlvX01lYW5fSFJfZGlmX3ogflRBU2MqYXJvdXNhbF9jKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAoMSB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAoMXxtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpLAogICAgIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWxfY2F0LCBwcmVkPSBhcm91c2FsX2MsIG1vZHggPSBUQVNjKQoKc3VtbWFyeShocl9kaWZfbW9kZWxzJGFyb3VzYWxfdmFsX2NhdCkKCnBsb3QoaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCkKcGxvdChocl9kaWZfbW9kZWxzJGFyb3VzYWxfdmFsX2NhdCkKCgoKCmBgYApzdW1tYXJ5KGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWxfY2F0KQoKCmhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWxfY2F0IDwtIGxtZXIoQmlvX01lYW5fSFJfZGlmfiAgbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyKiBtZWRpYW5zcGxpdF9zYW1wbGVfdmFsZW5jZTIrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICgxK21lZGlhbnNwbGl0X3NhbXBsZV92YWxlbmNlMiB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAoMXxtZWRpYW5zcGxpdF9zYW1wbGVfYXJvdXNhbDIpLAogICAgIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxKQoKCnN1bW1hcnkoaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbF9jYXQpCgppbnRlcmFjdGlvbnM6OmNhdF9wbG90KGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWxfY2F0LCBwcmVkID0gbWVkaWFuc3BsaXRfc2FtcGxlX2Fyb3VzYWwyLCBtb2R4ID0gbWVkaWFuc3BsaXRfc2FtcGxlX3ZhbGVuY2UyKQoKCmBgYAojIGNvcnJlbGF0aW9uCgpgYGB7cn0KZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxJT4lCiAgc3Vic2V0KCFpcy5uYShtZWRpYW5zcGxpdF9ncm91bmRfdmFsZW5jZSkpJT4lCiAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsIT0gIm91dGxpZXIiKSU+JQogIGdyb3VwX2J5KHNzaWQsbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIG1lZGlhbnNwbGl0X2dyb3VuZF9hcm91c2FsKSU+JQogIG11dGF0ZShjb3JfaHJfYXJvdXMgPSBjb3IoQmlvX01lYW5fSFJfZGlmLCBhcm91c2FsLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UsIGNvcl9ocl9hcm91cykpKwogICMgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAuMiwgd2lkdGggPSAuMikrCiAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC4yKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBzc2lkKSwgY29sb3IgPSAnZ3JheScsIG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoKSsKICBmYWNldF9ncmlkKH5tZWRpYW5zcGxpdF9ncm91bmRfYXJvdXNhbCkKCgoKYGBgCiAgIyB4bGltKC01LDMpCgpgYGB7cn0KZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxICU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKEFnZSwgVEFTYykpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKaHJfZGlmX21vZGVsczwtIGxpc3QoKQoKaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCA8LSBsbWVyKEJpb19NZWFuX0hSX2RpZn4gIChhcm91c2FsX2MqdmFsZW5jZV9jICkqIFRBU2MgKygxK2Fyb3VzYWxfYyB8IHNzaWQpICsgKDF8c3RpbUlBUFMpLAogICAgIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxKQoKc3VtbWFyeShocl9kaWZfbW9kZWxzJGFyb3VzYWxfdmFsKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWwsIHByZWQgPSBhcm91c2FsX2MsIG1vZHggPSBUQVNjKQoKCmhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWwgPC0gbG1lcihCaW9fTWVhbl9IUn4gIGFyb3VzYWxfYyogdmFsZW5jZV9jICsoMSthcm91c2FsX2N8IHNzaWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyArICgxfHN0aW1JQVBTKSwKICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSkKCnN1bW1hcnkoaHJfZGlmX21vZGVscyRhcm91c2FsX3ZhbCkKCiMgcGxvdChocl9kaWZfbW9kZWxzJGFyb3VzYWxfdmFsKQoKaW50ZXJhY3Rpb25zOjppbnRlcmFjdF9wbG90KGhyX2RpZl9tb2RlbHMkYXJvdXNhbF92YWwsIHByZWQgPSB2YWxlbmNlX2MsIG1vZHggPSBhcm91c2FsX2MpCgoKYGBgCgoKYGBgCgppbXBvcnQgSFJWIHJlc3RpbmcKYGBge3J9CgpSZXN0X0hSViA8LSByZWFkX2V4Y2VsKCJSZXN0IEhSVi54bHN4IikKVmlldyhSZXN0X0hSVikgIAoKUmVzdF9IUlYlPiUKICBnZ3Bsb3QoYWVzKFJNU1NEKSkrCiAgZ2VvbV9oaXN0b2dyYW0oKQoKUmVzdF9IUlYlPiUKICBnZ3Bsb3QoYWVzKFJNU1NEKSkrCiAgZ2VvbV9oaXN0b2dyYW0oKQoKUmVzdF9IUlYlPiUKICBnZ3Bsb3QoYWVzKE1FQU5IUikpKwogIGdlb21faGlzdG9ncmFtKCkKCkJJT19IUlZhbmFseXN5cyRzc2lkPC0gYXMuY2hhcmFjdGVyKEJJT19IUlZhbmFseXN5cyRzc2lkKQoKbGVmdF9qb2luKEJJT19IUlZhbmFseXN5cywgUmVzdF9IUlYsIGJ5ID0gInNzaWQiKSU+JQogIGdncGxvdChhZXMoUk1TU0QsIFJNTVNTRCkpKwogIGdlb21fcG9pbnQoKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKCgojIGxpYnJhcnkocmVhZHhsKQoKClJlc3RfcHJhY3RpY2VfSFJWIDwtIHJlYWRfZXhjZWwoIlJlc3QgKyBwcmFjdGljZSBIUlYueGxzeCIpClZpZXcoUmVzdF9wcmFjdGljZV9IUlYpClJlc3RfcHJhY3RpY2VfSFJWJHNzaWQ8LSBhcy5jaGFyYWN0ZXIoUmVzdF9wcmFjdGljZV9IUlYkc3NpZCkKCmxlZnRfam9pbihSZXN0X3ByYWN0aWNlX0hSViwgQklPX0hSVmFuYWx5c3lzLCBieSA9ICJzc2lkIiklPiUKICBnZ3Bsb3QoYWVzKFJNU1NELCBSTU1TU0QpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgoKbGVmdF9qb2luKFJlc3RfcHJhY3RpY2VfSFJWLCBSZXN0X0hSViwgYnkgPSAic3NpZCIpJT4lCiAgZ2dwbG90KGFlcyhSTVNTRC54LCBSTVNTRC55KSkrCiAgZ2VvbV9wb2ludCgpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKClJlc3RfcHJhY3RpY2VfSFJWJT4lCiAgZ2dwbG90KGFlcyhNRUFOSFIpKSsKICBnZW9tX2hpc3RvZ3JhbSgpCiAgCiMgaW1wb3J0IGhydiB0YXNrCmxpYnJhcnkocmVhZHhsKQpocnZSZXN1bHRzVGFzayA8LSByZWFkX2V4Y2VsKCJTdW1tYXJ5X2hydlJlc3VsdHNUYXNrLnhscyIpClZpZXcoaHJ2UmVzdWx0c1Rhc2spCgpgYGAKCmNvbWJpbmUgd2l0aCBkYXRhCgpgYGB7cn0KUmVzdF9IUlYKClJlc3RfSFJWJHN1YmplY3Q8LSBOVUxMCm5yb3coZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxKQojIDIxNjAKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MjwtIGxlZnRfam9pbihkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIFJlc3RfSFJWKQoKCiMgaHJ2IHJlc3QgdnMgaHJ0YXNrQ2FsbGJhY2tNYW5hZ2VyKApsZWZ0X2pvaW4oUmVzdF9IUlYsIGhydlJlc3VsdHNUYXNrLCBieSA9ICJzc2lkIikgJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoUk1TU0QueCwgUk1TU0QueSkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKSsKICB4bGltKDAsMTAwKSsKICB5bGltKDAsMTAwKQoKClJlc3RfSFJWJGhydmNvbmRpdGlvbjwtICJyZXN0IgpocnZSZXN1bHRzVGFzayRocnZjb25kaXRpb248LSAidGFzayIKCmxlZnRfam9pbihSZXN0X0hSViwgaHJ2UmVzdWx0c1Rhc2ssIGJ5ID0gInNzaWQiKSAlPiUKICBncm91cF9ieShzc2lkKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhSTVNTRC54LCBSTVNTRC55KSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpKwogIHhsaW0oMCwxMDApKwogIHlsaW0oMCwxMDApCgoKY29sbmFtZXMoaHJ2UmVzdWx0c1Rhc2spCmJpbmRfcm93cyhSZXN0X0hSViwgaHJ2UmVzdWx0c1Rhc2spJT4lCiAgc3Vic2V0KFJNU1NEPDEwMCklPiUKICBnZ3Bsb3QoYWVzKGhydmNvbmRpdGlvbiwgaGZwb3dlcikpKwogIGdlb21faml0dGVyKHdpZHRoID0gLjEsIGFscGhhID0gLjEpKwogIHN0YXRfc3VtbWFyeShnZW9tID0gJ3BvaW50cmFuZ2UnKSsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gc3NpZCksIGdlb20gPSAnbGluZScsIGFscGhhID0gLjEpCmBgYAoKCmBgYHtyfQpsZWZ0X2pvaW4oZGJfZnVsbDZuZXdfaHJfZml4X3N0aW1fbnQxLCBocnZSZXN1bHRzVGFzaykgJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBtdXRhdGUoY29yID0gY29yKGFyb3VzYWwsIHB1cF9iYXNDb3IsIHVzZSA9ICJjb21wbGV0ZSIpKSU+JQogICAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoTk41MCxjb3IgKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgeGxpbSgwLDUwMCkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgCiAgCiAgCiAgCiAgbGVmdF9qb2luKGRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MSwgaHJ2UmVzdWx0c1Rhc2spICU+JQogIGdyb3VwX2J5KHNzaWQpJT4lCiAgbXV0YXRlKGNvciA9IGNvcihhcm91c2FsLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICAgIGdyb3VwX2J5KHNzaWQpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBncm91cF9ieShzc2lkKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhUQVNjLCBOTjUwKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgICAgICMgeWxpbSgwLDIwMCkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgCiAgCiAgCiAgCiAgaHJ2UmVzdWx0c1Rhc2slPiUKICAgIGdncGxvdChhZXMoUk1TU0QpKSsKICAgIGdlb21faGlzdG9ncmFtKCkKCgogIAogIAogIGxlZnRfam9pbihkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIGhydlJlc3VsdHNUYXNrKSAlPiUKICAgIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSU+JQogICMgZ3JvdXBfYnkoc3NpZCklPiUKICAjIG11dGF0ZShjb3IgPSBjb3IoYXJvdXNhbCwgcHVwX2Jhc0NvciwgdXNlID0gImNvbXBsZXRlIikpJT4lCiAgICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhSTVNTRCxwdXBfYmFzQ29yLGNvbG9yID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgIyB4bGltKDAsMTAwKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKICAKICAKICAKICAgIGxlZnRfam9pbihkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIGhydlJlc3VsdHNUYXNrKSAlPiUKICAgIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSU+JQogICMgZ3JvdXBfYnkoc3NpZCklPiUKICAjIG11dGF0ZShjb3IgPSBjb3IoYXJvdXNhbCwgcHVwX2Jhc0NvciwgdXNlID0gImNvbXBsZXRlIikpJT4lCiAgICBncm91cF9ieShzc2lkLG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhSTVNTRCxCSU9fQ0RBLlBoYXNpY01heF96LGNvbG9yID0gbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UgKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgeGxpbSgwLDEwMCkrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgICAKICAgIAogICAgICAKICAgIGxlZnRfam9pbihkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDEsIGhydlJlc3VsdHNUYXNrKSAlPiUKICAgIHN1YnNldCghaXMubmEobWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpKSU+JQogICAgICAgc3Vic2V0KEJpb19NZWFuX0hSX2RpZl9vdXRsID09ICJub3Qgb3V0bGllciIpJT4lCiAgIyBncm91cF9ieShzc2lkKSU+JQogICMgbXV0YXRlKGNvciA9IGNvcihhcm91c2FsLCBwdXBfYmFzQ29yLCB1c2UgPSAiY29tcGxldGUiKSklPiUKICAgIGdyb3VwX2J5KHNzaWQsbWVkaWFuc3BsaXRfZ3JvdW5kX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKGBMRi9IRmAsQklPX0NEQS5QaGFzaWNNYXhfeixjb2xvciA9IG1lZGlhbnNwbGl0X2dyb3VuZF92YWxlbmNlICkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICMgeGxpbSgwLDUwMDApKwogIGdncHVicjo6c3RhdF9jb3IoKQpgYGAKICAKCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDIgJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoQmlvX01lYW5fSFJfZGlmLCBsZnBvd2VyKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCgpkYl9mdWxsNm5ld19ocl9maXhfc3RpbV9udDIgJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoTUVBTkhSLCBSTVNTRCkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogIGdncHVicjo6c3RhdF9jb3IoKQoKCmRiX2Z1bGw2bmV3X2hyX2ZpeF9zdGltX250MiAlPiUKICBncm91cF9ieShzc2lkKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgZ2dwbG90KGFlcyhNRUFOSFIsIEJpb19NZWFuX0hSKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNlID0gRikrCiAgZ2dwdWJyOjpzdGF0X2NvcigpCiAgCgoKYGBgCgoKYGBge3J9CiMgd29yayBvbiB0aGlzCmRiX2Z1bGw2bmV3XzMwNF91cCQKY29sbmFtZXMoZGJfZnVsbDRuZXdfc3RpbV9zY3JlZW5fcHVwaWxfbm9wcmFjdCkKY29sbmFtZXMoZGJfZnVsbDZuZXdfMzA0X3VwKQojIGRiX2Z1bGw2bmV3CnVuaXF1ZShkYl9mdWxsNm5ld18zMDRfdXAkc2NyZWVuY29udGVudCkKClZpZXcoZGJfZnVsbDZuZXcpCgojIHN0b3JlIGhlYXJ0IHJhdGUgYmFzZWxpbmUgdG8gY29tcHV0ZSBkaWZmZXJlbmNlCmRiX2Z1bGw2bmV3JEJpb19NZWFuX0hSX2ZpeCA9IGlmX2Vsc2UoZGJfZnVsbDZuZXckc2NyZWVuY29udGVudCA9PSAiZml4YXRpb24iLCBkYl9mdWxsNm5ldyRCaW9fTWVhbl9IUiwgTlVMTCkKCiMgY29tcHV0ZSBoZWFydCByYXRlIGRpZmZlcmVuY2UgdG8gZml4YXRpb24gc2NyZWVuCgpkYl9mdWxsNm5ld18zMDRfdXAkQmlvX01lYW5fSFIKVmlldyhkYl9mdWxsNm5ld18zMDRfdXApCgpkYl9mdWxsNm5ld18zMDRfdXA8LSBkYl9mdWxsNm5ld18zMDRfdXAlPiUKICBncm91cF9ieShzc2lkKSU+JQogIG11dGF0ZShCSU9fQ0RBLlBoYXNpY01heF96ID0gc2NhbGUoQklPX0NEQS5QaGFzaWNNYXgpWywxXSkKCgoKcHVwdWxyZXNpZHRlc3Q8LSBsbWVyKHB1cF9iYXNDb3IgfiBCUklHSFRORVNTYyArKDErQlJJR0hUTkVTU2N8c3NpZCksIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gdGVzdHJlc2lkZGYpCgpzdW1tYXJ5KHB1cHVscmVzaWR0ZXN0KQoKCnBsb3QocHVwdWxyZXNpZHRlc3QpCgpyZXNpZChwdXB1bHJlc2lkdGVzdCkKdHN0cmVzaWQgPC0gcmVzaWQocHVwdWxyZXNpZHRlc3QpCgoKdGVzdHJlc2lkZGYkcHVvcGlsX3Jlc2lkIDwtIHRzdHJlc2lkCgp0ZXN0cmVzaWRkZjwtIHN1YnNldChkYl9mdWxsNm5ld18zMDRfdXAsICFpcy5uYShwdXBfYmFzQ29yKSkKCgpzdW1tYXJ5KGxtZXIoYXJvdXNhbCB+IHB1cGlsX3Jlc2lkICsgKDF8c3NpZCksIFJFTUwgPSBGQUxTRSwKICAgICBkYXRhID0gdGVzdHJlc2lkZGYpKQoKCgpzdW1tYXJ5KGxtZXIoYXJvdXNhbCB+IHB1b3BpbF9yZXNpZCArIEJpb19NZWFuX0hSK0JJT19DREEuUGhhc2ljTWF4ICsgKDF8c3NpZCksCiAgICAgICAgICAgICAgIyAoMCtwdW9waWxfcmVzaWQgKyBCaW9fTWVhbl9IUitCSU9fQ0RBLlBoYXNpY01heHxzc2lkKSwgCiAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IHN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCkpKSAKCgpzdWJzZXQodGVzdHJlc2lkZGYsIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHNzaWQpKTw1MDApJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbiwgbmEucm0gPSBUUlVFKSU+JQogIGdncGxvdChhZXMoYXJvdXNhbCwgQklPX0NEQS5QaGFzaWNNYXgpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgc2UgPSBGKSsKICBnZ3B1YnI6OnN0YXRfY29yKCkKCnN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCklPiUKICBtdXRhdGUobWVkaWFuX2dyb3VuZF9hcm91c2FsID0gaWZfZWxzZShBcm91c2FsTWVhbj4gbWVkaWFuKEFyb3VzYWxNZWFuLCBuYS5ybSA9IFRSVUUpLCAiSGlnaCIsICJMb3ciKSklPiUKICBtdXRhdGUobWVkaWFuX2dyb3VuZF92YWxlbmNlID0gaWZfZWxzZShWYWxlbmNlTWVhbj4gbWVkaWFuKFZhbGVuY2VNZWFuLCBuYS5ybSA9IFRSVUUpLCAiTW9yZSBwb3NpdGl2ZSIsICJNb3JlIG5lZ2F0aXZlIikpJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICB1bmdyb3VwKCklPiUKICBtdXRhdGUobWVkaWFuX3NlbGZfYXJvdXNhbCA9IGlmX2Vsc2UoYXJvdXNhbD4gbWVkaWFuKGFyb3VzYWwpLCAiSGlnaCIsICJMb3ciKSklPiUKICBtdXRhdGUobWVkaWFuX3NlbGZfdmFsZW5jZSA9IGlmX2Vsc2UodmFsZW5jZT4gbWVkaWFuKHZhbGVuY2UpLCAiUG9zaXRpdmUiLCAiTmVnYXRpdmUiKSklPiUKZ3JvdXBfYnkoc3NpZCxtZWRpYW5fc2VsZl9hcm91c2FsLG1lZGlhbl9zZWxmX3ZhbGVuY2UpJT4lCiAgc3VtbWFyaXNlX2lmKGlzLm51bWVyaWMsIG1lYW4sIG5hLnJtID0gVFJVRSklPiUKICBnZ3Bsb3QoYWVzKG1lZGlhbl9zZWxmX2Fyb3VzYWwsIHB1b3BpbF9yZXNpZCwpKSsKICBnZW9tX2ppdHRlcih3aWR0aCA9IC4yLCBhbHBoYSA9IC4yKSsKICAgZ2VvbV9iYXIoc3RhdD0ic3VtbWFyeSIsIGZ1bi55ID0gIm1lYW4iLCBhbHBoYSA9IC4yKSsKICBzdGF0X3N1bW1hcnkoZ2VvbSA9ICdwb2ludHJhbmdlJykrCiAgICBmYWNldF9ncmlkKH5tZWRpYW5fc2VsZl92YWxlbmNlKQogIGdncHVicjo6c3RhdF9jb3IoKQogIAogIAogIAogIAogIHN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCklPiUKICBtdXRhdGUobWVkaWFuX2dyb3VuZF9hcm91c2FsID0gaWZfZWxzZShBcm91c2FsTWVhbj4gbWVkaWFuKEFyb3VzYWxNZWFuLCBuYS5ybSA9IFRSVUUpLCAiSGlnaCIsICJMb3ciKSklPiUKICBtdXRhdGUobWVkaWFuX2dyb3VuZF92YWxlbmNlID0gaWZfZWxzZShWYWxlbmNlTWVhbj4gbWVkaWFuKFZhbGVuY2VNZWFuLCBuYS5ybSA9IFRSVUUpLCAiTW9yZSBwb3NpdGl2ZSIsICJNb3JlIG5lZ2F0aXZlIikpJT4lCiAgZ3JvdXBfYnkoc3NpZCklPiUKICBtdXRhdGUobWVkaWFuX3NlbGZfYXJvdXNhbCA9IGlmX2Vsc2UoYXJvdXNhbD4gbWVkaWFuKGFyb3VzYWwpLCAiSGlnaCIsICJMb3ciKSklPiUKICBtdXRhdGUobWVkaWFuX3NlbGZfdmFsZW5jZSA9IGlmX2Vsc2UodmFsZW5jZT4gbWVkaWFuKHZhbGVuY2UpLCAiUG9zaXRpdmUiLCAiTmVnYXRpdmUiKSklPiUKZ3JvdXBfYnkoc3NpZCxtZWRpYW5fc2VsZl9hcm91c2FsKSU+JQogIHN1bW1hcmlzZV9pZihpcy5udW1lcmljLCBtZWFuLCBuYS5ybSA9IFRSVUUpJT4lCiAgICBzdWJzZXQoIWlzLm5hKG1lZGlhbl9zZWxmX2Fyb3VzYWwpKSU+JQogIGdncGxvdChhZXMobWVkaWFuX3NlbGZfYXJvdXNhbCwgQklPX0NEQS5QaGFzaWNNYXhfeikpKwogIGdlb21faml0dGVyKHdpZHRoID0gLjIsIGFscGhhID0gLjIpKwogICBnZW9tX2JhcihzdGF0PSJzdW1tYXJ5IiwgZnVuLnkgPSAibWVhbiIsIGFscGhhID0gLjIpKwogICAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBzc2lkKSxtZXRob2QgPSAnbG0nLCBzZSA9IEYpKwogICAgIyBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3NpZCkpCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAncG9pbnRyYW5nZScpCiAgICBmYWNldF9ncmlkKH5tZWRpYW5fc2VsZl92YWxlbmNlKQogIGdncHVicjo6c3RhdF9jb3IoKQogIAogIAogIHN1bW1hcnkobG1lcihhcm91c2FsIH4gbG9nKEJJT19DREEuUGhhc2ljTWF4Ky4xKSArICgxfHNzaWQpICsgKDErbG9nKEJJT19DREEuUGhhc2ljTWF4Ky4xKXxzdGltSUFQUyksCiAgICAgICAgICAgICAgIyAoMCtwdW9waWxfcmVzaWQgKyBCaW9fTWVhbl9IUitCSU9fQ0RBLlBoYXNpY01heHxzc2lkKSwgCiAgICAgICAgICAgICBSRU1MID0gRkFMU0UsCiAgICAgZGF0YSA9IHN1YnNldCh0ZXN0cmVzaWRkZiwgYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc3NpZCkpPDUwMCAmQklPX0NEQS5BbXBTdW0+IC4xKSkpCgoKCgoKCmBgYAoKCgoKCg==